2010-09-06 40 views
0

下面,初始加载(编辑),一切都显示正常。然而,当我POST(下面的动作)时,它看起来像它,并试图分别抓住ProductAttribute模型,与产品的ID,并立即失败。如何让我的Binder实现不尝试将集合重新绑定为单独的实体?ModelBinder NHibernate复杂对象与集合

谢谢!

型号

public class Product { 
    virtual public long Id { get; set; } 

    virtual public string Name { get; set; } 

    private IList<ProductAttribute> _productAttributes; 

    public virtual IList<ProductAttribute> ProductAttributes { 
     get{ 
     if(_productAttributes == null){ 
      _productAttributes = new List<ProductAttribute>(); 
     } 
     return _productAttributes; 
     } 
     set{ 
     _productAttributes = value; 
     } 
    } 
} 

查看

<%using (Html.BeginForm(new {id = Model.Id > 0 ? (long?)Model.Id : null})) {%> 
<table class="form"> 
    <% for(var i=0; i < Model.ProductAttributes.Count; i++){ 
    var pa = Model.ProductAttributes[i]; %> 
    <tr> 
    <th><%: Model.ProductAttributes[i].Name %></th> 
    <td> 
    <%: Html.Hidden("ProductAttributes.Index", i) %> 
    <% if(pa.CanSpecifyValueDirectly()){ %> 
    <%: Html.TextBoxFor(model => model.ProductAttributes[i].Value) %> 
    <% } else { %> 
    <%: Html.DropDownListFor(model => model.ProductAttributes[i].Value, new SelectList(pa.MarketAttribute.AttributeLevels, "id", "Name", pa.AttributeLevel)) %> 
    <% } %> 
    </td> 
    </tr> 
    <input type="submit" value="Save" /> 
</table> 
<%}%> 

控制器

public ActionResult Edit(long id, Product product) { 
    ViewData.Model = product; 
    if (ModelState.IsValid) { 
     var results = product.Update(); 
     ViewData["results"] = results; 
     if (!results.Error) { 
      return RedirectToAction("Show", new { id = id }); 
     } 
    } 

    return View(); 
} 

粘结剂

public class StackModelBinder : DefaultModelBinder { 
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) { 
     var modelInterface = modelType.GetInterface("IModel"); 
     if (modelInterface == null) { 
      return base.CreateModel(controllerContext, bindingContext, modelType); 
     } 

     var value = bindingContext.ValueProvider.GetValue("id").RawValue.ToString(); 
     if (string.IsNullOrEmpty(value)) { 
      return base.CreateModel(controllerContext, bindingContext, modelType); 
     } 

     var id = Convert.ChangeType(value, typeof (long)); 
     var assembly = Assembly.GetAssembly(modelType); 
     var dao = assembly.GetType(string.Concat(assembly.GetName().Name, ".core.GlobalDao`1[", modelType.FullName, "]")); 

     if (dao == null) { 
      return base.CreateModel(controllerContext, bindingContext, modelType); 
     } 

     var method = dao.GetMethod("Get"); 
     return method.Invoke(null, new[] {id}); 
    } 
} 

回答

1

通常情况下,这是一个坏主意,通过模型绑定推动实体 - 他们往往是有点太复杂,它来处理,不要介意在现代奥姆斯那张令人兴奋的东西,这样的作为动态代理,可以给ModelBinder或ORM配合。

这里最好的办法就是改变规则并建立一个专门的课程来进行编辑并将其传送给控制器。这个类可以是ModelBinder友好的,并且您可以获得将UI与域实体分开的额外好处。

+0

为了DRY的利益,我不得不维护两个本质上代表同一事物的对象。其他解决方案? – hoffmanc 2010-09-06 14:49:19

+0

哦,我觉得你干旱。除了它不是一回事 - 一个负责将数据带入控制器,另一个负责作为您的域实体。认为CQRS没有重复的代码。 – 2010-09-06 19:01:09