CslaModelBinder没有绑定子列表

时间:2015-02-04 20:32:51

标签: asp.net-mvc csla

我有以下业务类

public class EditableRoot:Csla.BusinessBase<EditableRoot>
{
    public string Name { get; private set; }
    public int Id { get; private set; }

    public static EditableRoot New() {
        return DataPortal.Create<EditableRoot>();
    }

    public static readonly PropertyInfo<EditableChildList> ChildListProperty = RegisterProperty<EditableChildList>(c => c.ChildList, RelationshipTypes.Child);
    public EditableChildList ChildList
    {
        get { return GetProperty(ChildListProperty); }
        private set { SetProperty(ChildListProperty, value); }
    }
    protected override void DataPortal_Create()
    {
        ChildList = EditableChildList.New();
    }

}
public class EditableChildList : Csla.BusinessListBase<EditableChildList,EditableChild>
{
    public static EditableChildList New() { return DataPortal.CreateChild<EditableChildList>(); }
}
public class EditableChild : Csla.BusinessBase<EditableChild>
{
    public static readonly PropertyInfo<string> AssignedByProperty = RegisterProperty<string>(c => c.AssignedBy);
    public string AssignedBy
    {
        get { return GetProperty(AssignedByProperty); }
        private set { LoadProperty(AssignedByProperty, value); }
    }
    public static readonly PropertyInfo<int> DocTypeIDProperty = RegisterProperty<int>(c => c.DocTypeID);
    public int DocTypeID
    {
        get { return GetProperty(DocTypeIDProperty); }
        set { SetProperty(DocTypeIDProperty, value); }
    }
    public static EditableChild New(int docTypeId) { return DataPortal.CreateChild<EditableChild>(docTypeId); }
    void Child_Create(int docTypeId)
    {
        DocTypeID = docTypeId;
        AssignedBy = "AssignedBy" + docTypeId;
    }

}

我有控制器

 public class ComplexTypeController : Csla.Web.Mvc.Controller, Csla.Web.Mvc.IModelCreator
{
    //
    // GET: /ComplexType/
    public ActionResult Create()
    {
        EditableRoot type = EditableRoot.New();
        ViewData.Model = type;
        return View();
    }

    [HttpPost]
    public ActionResult Create(EditableRoot complexType, FormCollection collection, string submit)
    {
        if (submit != "Create")
        {
            Random rand = new Random();

            complexType.ChildList.Add(EditableChild.New(rand.Next()));

        }
        ViewData.Model = complexType;
        return View();
    }

    public object CreateModel(Type modelType)
    {
        if (modelType == typeof(EditableRoot))
            return EditableRoot.New();
        else if (modelType == typeof(EditableChildList))
            return EditableChildList.New();
        else if (modelType == typeof(EditableChild))
            return EditableChild.New(0);
        else
            return Activator.CreateInstance(modelType);
    }
}

我有观点

 @model EditableRoot

 @{
     ViewBag.Title = "Create";
 }

 <h2>Create</h2>
 @using (Html.BeginForm())
 {
     @Html.DisplayFor(m => m.Name);
     @Html.HiddenFor(m => m.Id);
     <table>
         <thead>
             <tr>
                 <th>Child Type Name</th>
                 <td>Child Type Id</td>
             </tr>
         </thead>


    <tbody>
            @for (int i = 0; i < Model.ChildList.Count(); i++)
            {
                <tr>
                    <td>
                        @Html.TextBoxFor(a => Model.ChildListIdea.AssignedBy)
                    </td>
                    <td>
                        @Html.TextBoxFor(a => Model.ChildListIdea.DocTypeID)
                    </td>
                </tr>
            }
        </tbody>
    </table>
   <input name="submit" type="submit" id="submit" value="Create" />
    <input name="submit" type="submit" id="process" value="Add Child" />                       
}

当我通过点击&#34;添加孩子&#34;添加EditableChild时按钮然后单击&#34;创建&#34;按钮公共ActionResult Create(EditableRoot complexType,FormCollection集合,字符串提交)调用中的EditableRoot对象的ChildList属性未绑定。

换句话说,子列表EditableRoot.ChildList未绑定,列表中没有项目,即使视图中的html遵循绑定复杂类型列表的约定。当我在浏览器中查看实际的html时,为EditableRoot.ChildList中的项目发出的行是存在且正确命名的。

但是,我从github获得了CslaModelBinder并将其放入我的项目并连接mvc默认模型绑定器以使用它。然后我改变了CslaModelBinder方法

公共覆盖对象BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext)

看起来像这样

public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
            {
                //if (typeof(Csla.Core.IEditableCollection).IsAssignableFrom((bindingContext.ModelType)))
                //    return BindCslaCollection(controllerContext, bindingContext);

                var suppress = bindingContext.Model as Csla.Core.ICheckRules;
                if (suppress != null)
                    suppress.SuppressRuleChecking();
                var result = base.BindModel(controllerContext, bindingContext);
                return result;
            }

一切顺利。 EditableRoot.ChildList属性已绑定,预期的项目位于列表中。

最终我修改了CslaModelBinder方法

公共覆盖对象BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext)

注释掉绑定Csla IEditableCollection的处理,因此该方法最终在基类DefaultModelBinder上调用BindModel方法。哪个有用。

但是,如果我使用我修改过的CslaModelBinder,我会在其他地方遇到问题吗?

如果DefaultModelBinder可以处理Csla.Core.IEditableCollection类型的绑定,那么为什么

if(typeof(Csla.Core.IEditableCollection).IsAssignableFrom((bindingContext.ModelType)))                     return BindCslaCollection(controllerContext,bindingContext);

???

1 个答案:

答案 0 :(得分:0)

围绕子集合绑定存在已知问题,并提供解决问题的开放票证。

请参阅https://github.com/MarimerLLC/csla/issues/19