我正在尝试了解自定义绑定应该如何工作。
假设一个简单的动作
[HttpPost]
public ActionResult MyAction(CustomType parameter) {
// do something
}
...以及以下表单数据
{
parameter : "mydata"
parameter.Property1 : "something"
parameter.Property2 : 3
}
...以及以下非常简单的自定义活页夹
public class MyBinder : DefaultModelBinder {
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
if (bindingContext.ModelType.Equals(typeof(CustomType))) {
string parameter = controllerContext.HttpContext.Request.Form[bindingContext.ModelName];
object model = controllerContext.HttpContext.Cache[parameter];
return model;
}
return base.BindModel(controllerContext, bindingContext);
}
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) {
// not called
return base.CreateModel(controllerContext, bindingContext, modelType);
}
protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor) {
// not called
base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
}
}
我可以看到调用BindModel
方法。但是,一旦我返回自定义对象,就永远不会为BindProperty
和Property1
调用Property2
方法。这是有道理的,因为我没有打电话给base.BindModel()
。
所以我的问题是:应该 BindModel
如何实现,以便在超类中创建CustomType
并调用BindModel
?
答案 0 :(得分:0)
我暂时没有这样做,但是IIRC,您可以使用属性集来构建新的CustomType,而不是return new CustomType();
类似的东西:
return new CustomType
{
Property1 = request.Form.Get("Property1"),
...
};
答案 1 :(得分:0)
我检查了DefaultModelBinder的源代码,发现了内部方法BindComplexElementalModel
。使用此自定义数据绑定器可以实现所需的模型绑定行为。
public class MyBinder : DefaultModelBinder {
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
if (bindingContext.ModelType.Equals(typeof(CustomType))) {
// get an instance of the model using the model prefix
string parameter = controllerContext.HttpContext.Request.Form[bindingContext.ModelName];
object model = controllerContext.HttpContext.Cache[parameter];
// populate the remaining model properties using reflection (yuck)
MethodInfo bindComplexElementalModel =
base.GetType().GetMethod("BindComplexElementalModel", BindingFlags.NonPublic | BindingFlags.Instance);
bindComplexElementalModel.Invoke(this, new object[] { controllerContext, bindingContext, model });
return model;
}
return base.BindModel(controllerContext, bindingContext);
}
}
当然,使用内部框架方法并不是一个干净的解决方案,因此我将这个问题保持开放,希望有人能提供更好的答案。