我需要基于派生类型创建动态输入表单,但是当传递给控制器的POST方法时,我无法正确绑定复杂的属性。其他属性绑定良好。这是我所拥有的一个人为的示例:
模型
public abstract class ModelBase {}
public class ModelDerivedA : ModelBase
{
public string SomeProperty { get; set; }
public SomeType MySomeType{ get; set; }
public ModelDerivedA()
{
MySomeType = new SomeType();
}
}
public class SomeType
{
public string SomeTypeStringA { get; set; }
public string SomeTypeStringB { get; set; }
}
定制模型活页夹
活页夹基于以下答案:polymorphic-model-binding
public class BaseViewModelBinder : DefaultModelBinder
{
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
var typeValue = bindingContext.ValueProvider.GetValue("ModelType");
var type = Type.GetType(
(string)typeValue.ConvertTo(typeof(string)),
true
);
if (!typeof(ModelBase).IsAssignableFrom(type))
{
throw new InvalidOperationException("The model does not inherit from mode base");
}
var model = Activator.CreateInstance(type);
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, type);
return model;
}
}
控制器
[HttpPost]
public ActionResult GetDynamicForm([ModelBinder(typeof(BaseViewModelBinder))] ModelBase model)
{
// model HAS values for SomeProperty
// model has NO values for MySomeType
}
查看节选
@Html.Hidden("ModelType", Model.GetType())
@Html.Test(Model);
的JavaScript
使用$.ajax
来发布表单data: $(this).serialize()
,如果我进行调试,则显示正确的填充表单数据。
除的属性外,所有属性均填充到模型中SomeType
。我需要更改哪些内容才能填充它们?
谢谢
我已经通过以下方式解决了我眼前的问题:
FormvalueProvider
(以访问已发布的内容)递归地浏览我的模型并将每个属性值设置为 FormValueProvider
private FormValueProvider vp;
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
var typeValue = bindingContext.ValueProvider.GetValue("ModelType");
var type = Type.GetType(
(string)typeValue.ConvertTo(typeof(string)),
true
);
if (!typeof(ModelBase).IsAssignableFrom(type))
{
throw new InvalidOperationException("Bad Type");
}
var model = Activator.CreateInstance(type);
vp = new FormValueProvider(controllerContext);
bindingContext.ValueProvider = vp;
SetModelPropertValues(model);
return model;
}
而递归的基础上,这个答案在这里,以打印嵌套对象的属性
private void SetModelPropertValues(object obj)
{
Type objType = obj.GetType();
PropertyInfo[] properties = objType.GetProperties();
foreach (PropertyInfo property in properties)
{
object propValue = property.GetValue(obj, null);
var elems = propValue as IList;
if (elems != null)
{
foreach (var item in elems)
{
this.SetModelPropertValues(item);
}
}
else
{
if (property.PropertyType.Assembly == objType.Assembly)
{
this.SetModelPropertValues(propValue);
}
else
{
property.SetValue(obj, this.vp.GetValue(property.Name).AttemptedValue, null);
}
}
}
}
任何使用此功能的人都可能需要使其更强大,以满足他们的需求。
我很想知道作为解决此类问题的一般方法所存在的任何弊端。
但是,我希望这篇文章对某些情况有所帮助。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句