У меня есть следующие бизнес-классыCslaModelBinder не обязательный список ребенка
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" />
}
Когда я добавить EditableChild, нажав кнопку «Добавить ребенка», затем нажмите кнопку «Создать» для свойства ChildList объекта EditableRoot в публикации ic Создание ActionResult Create (коллекция EditableRoot complexType, CollectionCollection, string submit) не привязана.
Другими словами, дочерний список EditableRoot.ChildList не связан, нет элементов в списке, хотя html в представлении следует соглашениям для привязки списков сложных типов. И когда я просматриваю фактический html в браузере, строки, испускаемые для элементов в EditableRoot.ChildList, присутствуют и правильно названы.
Тем не менее, я получил CslaModelBinder из github и поместил его в свой проект и подключил к нему mvc default modelbinder, чтобы использовать его. Тогда я изменил метод 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 и поэтому метод в конечном счете вызывает метод BindModel на базе класс, DefaultModelBinder. Что работает.
Но, если я использую модифицированный CslaModelBinder, я столкнусь с проблемами в другом месте?
Если DefaultModelBinder может обрабатывать связывание типов Csla.Core.IEditableCollection то почему
если (TypeOf (Csla.Core.IEditableCollection) .IsAssignableFrom ((bindingContext.ModelType))) возвращение BindCslaCollection (controllerContext, BindingContext) ;
???
Здравствуйте, Андрей, вы думали о фиксации метода BindCslaCollection в CslaModelBinder? Эта проблема официально обозначена как «нужна помощь». –
@MichaelCsikos, нет Я не исправил BindCslaCollection. Прошло некоторое время с тех пор, как я просмотрел этот код, но нам пришлось как-то обойти его. – andrewramka