2010-09-06 71 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