我有一个基类、一组子类和一个集合容器,用于使用局部视图动态创建和填充控件。
// base class
public class SQControl
{
[Key]
public int ID { get; set; }
public string Type { get; set; }
public string Question { get; set; }
public string Previous { get; set; }
public virtual string Current { get; set; }
}
// subclass
public class SQTextBox : SQControl
{
public SQTextBox()
{
this.Type = typeof(SQTextBox).Name;
}
}
//subclass
public class SQDropDown : SQControl
{
public SQDropDown()
{
this.Type = typeof(SQDropDown).Name;
}
[UIHint("DropDown")]
public override string Current { get; set; }
}
// collection container used as the Model for a view
public class SQControlsCollection
{
public List<SQControl> Collection { get; set; }
public SQControlsCollection()
{
Collection = new List<SQControl>();
}
}
我在运行时根据需要使用 SQControl 的不同子类填充 Collection 控件,并且在 EditorTemplates 中我为每个子类提供了单独的视图。在集合项目上使用 Html.EditorFor 我可以使用适当的控件动态生成表单。
这一切都很好。
我遇到的问题是,当我保存表单时,MVC 绑定无法判断 Collection 中的每个项目是用什么子类创建的,而是将它们绑定到基类 SQControl 的实例。
这会使视图引擎感到困惑,因为它无法确定要加载的正确视图,而只是加载默认视图。
我目前的解决方法是将子类的“类型”保存为模型中的一个字段,然后在回发时,我将集合复制到一个新容器中,根据中的信息使用正确的子类重新创建每个对象类型字段。
public static SQControlsCollection Copy(SQControlsCollection target)
{
SQControlsCollection newCol = new SQControlsCollection();
foreach (SQControl control in target.Collection)
{
if (control.Type == "SQTextBox")
{
newCol.Collection.Add(new SQTextBox { Current = control.Current, Previous = control.Previous, ID = control.ID, Question = control.Question });
}
else if (control.Type == "SQDropDown")
{
newCol.Collection.Add(new SQDropDown { Current = control.Current, Previous = control.Previous, ID = control.ID, Question = control.Question });
}
...
}
return newCol;
}
所以我的问题是,有没有更好的方法来维护回发之间的基本类型集合中的项目类型?我知道在 MVC 中为每个模型都有一个类型化的视图是一种做法,但我希望能够使用可重用的部分视图基于 XML 文档动态构建视图。