我正在使用休眠和 MVC3。我有两个简单的模型和一个视图模型,其中包含它自己的一些属性+每个模型的一个属性。
例如
class Contact() { ... }
class Address() { ... }
class EditContactVM() { 
    public string something {get;set;}
    public Contact contact {get;set;}
    public Address address {get;set;}
}
所有基本模型都实现了一个接口 (IMyModel),它具有一个 Id 属性和一些其他位。
我有一个通用模型绑定器,它从视图发回的数据中提取 Id 并从数据库中获取对象:
public class NHibernateModelBinder<T> : DefaultModelBinder where T: IMyModel
{
    private DataAccessService DataAccessService { get; set; }
    public NHibernateModelBinder(DataAccessService dataAccessService)
    {
        DataAccessService = dataAccessService;
    }
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        ValueProviderResult IdResult = bindingContext.ValueProvider.GetValue("Id");
        IAgBiTechModel model = null;
        if (IdResult != null)
        {
            model = DataAccessService.Get<T>(Convert.ToInt32(IdResult.AttemptedValue));
        }
        return model;
    }
}
以及为该类型创建适当的绑定器的模型绑定器提供程序。
这一切都很完美,我最终在我的控制器中使用了一个 EditContactVM 对象,该对象填充了从数据库中适当填充的属性。
然而,有一件事让我感到困惑:据我所知,在模型绑定器完成它并从数据库中获取实体之后,应该使用从视图回发的值来更新对象的属性。
例如,我正在编辑 ID 为 5 的联系人。联系人姓名在视图上从“James”更新为“Tom”。在回发时,模型绑定器将从数据库中获取联系人 5 并将其分配给 EditContactVM.Contact。--- 现在我希望 MVC 使用我视图中的数据更新 EditContactVM.Contact。即当我到达我的控制器时,EditContactVM.Contact.Name 将是“Tom”。相反,我只是获取未修改的 DB 对象并丢失视图发回的数据。
我能想到的唯一可能相关的另一件事是 EditContactVMBinder 看起来像这样:
public class ContactVMBinder : DefaultModelBinder
{
    private Func<ContactVM> EmptyViewModelFactory { get; set; }
    public ContactVMBinder(Func<ContactVM> emptyViewModelFactory)
    {
        EmptyViewModelFactory = emptyViewModelFactory;
    }
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        bindingContext.ModelMetadata.Model = EmptyViewModelFactory();
        return base.BindModel(controllerContext, bindingContext);
    }
}
编辑:添加了一些视图标记
@using (Html.BeginForm("Edit", "Contact", FormMethod.Post)) {
    <div class="row">
        @Html.ValidationSummary(true)
    </div>
    @Html.HiddenFor(m => m.contact.Id)
    @Html.HiddenFor(m => m.contact.Timestamp)
    if (Model.address != null && Model.address.Id > 0)
    {
        @Html.HiddenFor(m => m.address.Id);
        @Html.HiddenFor(m => m.address.Timestamp)
    }
    <div class="row">
        <h4>Contact Details</h4>
    </div>
    <div class="editor-label row">
        @Html.LabelFor(m => m.contact.FirstName)
    </div>
    <div class="editor-field row">
        @Html.TextBoxFor(m => m.contact.FirstName)
        <span style="margin: 2">
            @Html.ValidationMessageFor(m => m.contact.FirstName)
        </span>
    </div>
}