具有集合的ModelBinder NHibernate复杂对象

时间:2010-09-06 14:03:01

标签: asp.net-mvc-2 modelbinders model-binding

下面,在初始加载(编辑)时,一切正常。但是,当我发布POST(下面的操作)时,它看起来就像是一样,并尝试使用产品的ID分别获取ProductAttribute模型,这会立即失败。如何保持我的Binder实现不会尝试将集合重新绑定为单独的实体?

谢谢!

模型

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 个答案:

答案 0 :(得分:1)

通常,将实体推送到模型绑定器是一个坏主意 - 它们往往有点太复杂而无法处理,更不用说现代ORM中发生的令人兴奋的事情,例如动态代理,可以给ModelBinder或ORM适合。

这里最好的选择是更改规则并构建一个专门的类来进行编辑并将其传输到控制器。这个类可以是ModelBinder友好的,你可以将UI与域实体分开。