我是不是误解了mvc模型绑定和NHibernate的交互?

本文关键字:NHibernate 交互 绑定 模型 是不是 误解 mvc | 更新日期: 2023-09-27 18:15:07

我使用nhibernate &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对象,该对象填充了从数据库中适当填充的属性。

然而,有一件事让我困惑:正如我所理解的,在模型绑定器做它的事情并从DB获得实体之后,对象的属性应该用从视图传回的值进行更新。

。我正在编辑Id 5的联系人。联系人姓名在视图上从'James'更新为'Tom'。在发回时,模型绑定器将从DB中获取联系人5,并将其分配给EditContactVM.Contact。——现在我希望MVC更新EditContactVM。接触数据从我的观点。例如,当我到达我的控制器时,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>
}

我是不是误解了mvc模型绑定和NHibernate的交互?

通过重写BindModel,您有效地告诉框架不要做"它的事情",您将自己绑定模型。你必须调用super.BindModel()让框架将数据从视图绑定到它为你创建的实例。另一种方法是重写OnModelUpdated(),在这个阶段,框架已经为您创建了一个模型实例,并使用视图中的数据填充它(调用super.BindModel后可以在BindModel中获得相同的结果),然后您可以用您想要从数据库中检索的任何内容更新该实例。