ASP.NET MVC 2 RC模型与NHibernate和下拉列表绑定

我在使用NHibernate进行数据访问的ASP.NET MVC 2 RC应用程序中遇到模型绑定问题.我们正在尝试以
Ruby on Rails方式构建应用程序,并且具有一个非常简单的体系结构,其中域实体从数据库到视图一直使用.

该应用程序有几个域实体,可以通过以下两个类来说明:

public class Product {
    ...

    public Category Category { get; set; }      
}

public class Category {
    public int Id { get; set; }
    public string Name { get; set; }
}

在呈现编辑表单的视图中,显示下拉列表的语句如下:

<%= Html.DropDownListFor(model => model.Category.Id, 
       new SelectList(ViewData["categories"] as IList<Category>, "Id", "Name"), 
       "-- Select Category --" ) %>

请忽略使用“非类型”视图数据来保存类别集合.

接收表单的操作方法类似于以下内容.请注意,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设置为在表单中选择的值,例如Category.Id =“2”.使用默认模型绑定器会导致以下类型的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"))

所以我像Bryan建议的那样删除了’.Id’.在更改之前,模型仅包含Employee的Id,并且在更改之后,Binder还将员工的所有详细信息加载到模型中.

点赞