我在使用 NHibernate 进行数据访问的 ASP.NET MVC 2 RC 应用程序中的模型绑定(bind)存在问题。我们正在尝试以 Ruby on Rails 的方式构建应用程序,并拥有一个非常简单的架构,其中域实体从数据库到 View 一直被使用。
该应用程序有几个域实体,可以通过以下两个类来说明:
public class Product {
...
public Category Category { get; set; }
}
public class Category {
public int Id { get; set; }
public string Name { get; set; }
}
在呈现编辑表单的 View 中,有以下语句来显示下拉列表:
<%= Html.DropDownListFor(model => model.Category.Id,
new SelectList(ViewData["categories"] as IList<Category>, "Id", "Name"),
"-- Select Category --" ) %>
请忽略使用“非类型化” View 数据来保存类别集合。
接收表单 post 的操作方法类似于以下内容。请注意,TransactionFilter 属性添加 NHibernate 事务处理并在没有异常发生且验证成功时提交事务。
[HttpPost]
[TransactionFilter]
public ActionResult Edit(int id, FormCollection collection) {
var product = _repository.Load(id);
// Update the product except the Id
UpdateModel(product, null, null, new[] {"Id"}, collection);
if (ModelState.IsValid) {
return RedirectToAction("Details", new {id});
}
return View(product);
}
我的问题是 product.Category.Id 设置为在表单中选择的值,例如类别.Id = "2"。使用默认模型绑定(bind)器会导致以下类型的 NHibernate 异常:
identifier of an instance of Name.Space.Entities.Category was altered from 4 to 2
这很有意义,因为产品已经分配了一个类别,并且只有该现有类别的主键正在更改。应该分配另一个类别实例。
我想可以创建一个自定义 ModelBinder 来处理这个问题,但是有没有更简单的方法来完成这个工作?可以(并且应该)修改域实体来处理这个问题吗?
最佳答案
我通过更改以下行解决了编辑页面上组合框的类似问题
@Html.DropDownListFor(x => x.Employee.Id, new SelectList(ViewBag.Employees, "Id", "DisplayName"))
经过
@Html.DropDownListFor(x => x.Employee, new SelectList(ViewBag.Employees, "Id", "DisplayName"))
所以我像布莱恩建议的那样删除了“.Id”。更改前,模型只包含员工的 Id,更改后,Binder 还将员工的所有详细信息加载到模型中。
关于nhibernate - ASP.NET MVC 2 RC 模型与 NHibernate 和下拉列表绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2052886/