Thu*_*ein 7 c# model-view-controller asp.net-mvc modelbinders
我有一个这样的动作方法如下.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Form newForm)
{
...
}
Run Code Online (Sandbox Code Playgroud)
我有一个包含以下类的模型,我想从ajax JSON数据加载数据.
public class Form
{
public string title { get; set; }
public List<FormElement> Controls { get; set; }
}
public class FormElement
{
public string ControlType { get; set; }
public string FieldSize { get; set; }
}
public class TextBox : FormElement
{
public string DefaultValue { get; set; }
}
public class Combo : FormElement
{
public string SelectedValue { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这是JSON数据.
{ "title": "FORM1",
"Controls":
[
{ "ControlType": "TextBox", "FieldSize": "Small" ,"DefaultValue":"test"},
{ "ControlType": "Combo", "FieldSize": "Large" , "SelectedValue":"Option1" }
]
}
$.ajax({
url: '@Url.Action("Create", "Form")',
type: 'POST',
dataType: 'json',
data: newForm,
contentType: 'application/json; charset=utf-8',
success: function (data) {
var msg = data.Message;
}
});
Run Code Online (Sandbox Code Playgroud)
DefaultModelBinder正在处理嵌套对象结构,但它无法解析不同的子类.
使用相应的子类加载List的最佳方法是什么?
我查看了 mvc DefaultModelBinder 实现的代码。绑定模型时 DefaultModelBinder 使用 GetModelProperties() 查找模型的属性。以下是 DefaultModelBinder 如何查找属性:
protected virtual ICustomTypeDescriptor GetTypeDescriptor(ControllerContext controllerContext, ModelBindingContext bindingContext) {
return TypeDescriptorHelper.Get(bindingContext.ModelType);
}
Run Code Online (Sandbox Code Playgroud)
TypeDescriptorHelper.Get 使用 ModelType,它是父类型(在我的例子中为 FormElement),因此不会检索子类(TextBox、Combo)的属性。
您可以重写该方法并更改行为以检索特定子类型,如下所示。
protected override System.ComponentModel.PropertyDescriptorCollection GetModelProperties(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
Type realType = bindingContext.Model.GetType();
return new AssociatedMetadataTypeTypeDescriptionProvider(realType).GetTypeDescriptor(realType).GetProperties();
}
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
ValueProviderResult result;
result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".ControlType");
if (result == null)
return null;
if (result.AttemptedValue.Equals("TextBox"))
return base.CreateModel(controllerContext,
bindingContext,
typeof(TextBox));
else if (result.AttemptedValue.Equals("Combo"))
return base.CreateModel(controllerContext,
bindingContext,
typeof(Combo));
return null;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
440 次 |
| 最近记录: |