我正在努力理解自定义绑定应该如何工作。
假设一个简单的动作
[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?
发布于 2015-04-17 14:49:37
我已经有一段时间没有这样做了,但是IIRC可以用属性集来构造新的CustomType,而不是return new CustomType();
类似于:
return new CustomType
{
Property1 = request.Form.Get("Property1"),
...
};发布于 2015-04-19 08:55:52
我已经检查了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);
}
}当然,使用内部框架方法并不是一个干净的解决方案,所以我不想问这个问题,希望有人能提供一个更好的答案。
https://stackoverflow.com/questions/29701922
复制相似问题