用于绑定嵌套属性值的自定义模型绑定器
我需要这个的原因是:在我的一个控制器中,我想以与应用程序的其余部分不同的方式绑定所有 Decimal 值。我不想在 Global.asax 中注册模型绑定器(通过 ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());)
我尝试从 DefaultModelBinder 派生 类并重写其 BindProperty
方法,但这仅适用于模型实例的直接(而非嵌套)Decimal 属性。
我有以下示例来演示我的问题:
namespace ModelBinderTest.Controllers
{
public class Model
{
public decimal Decimal { get; set; }
public DecimalContainer DecimalContainer { get; set; }
}
public class DecimalContainer
{
public decimal DecimalNested { get; set; }
}
public class DecimalModelBinder : DefaultModelBinder
{
protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor)
{
if (propertyDescriptor.PropertyType == typeof (decimal))
{
propertyDescriptor.SetValue(bindingContext.Model, 999M);
return;
}
base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
}
}
public class TestController : Controller
{
public ActionResult Index()
{
Model model = new Model();
return View(model);
}
[HttpPost]
public ActionResult Index([ModelBinder(typeof(DecimalModelBinder))] Model model)
{
return View(model);
}
}
}
此解决方案仅将 Model
的 Decimal
属性设置为 999,但不对 DecimalContainer
执行任何操作code> 的 DecimalNested
属性。我意识到这是因为 DecimalModelBinder
的 BindProperty
覆盖中调用了 base.BindProperty
,但我不知道如何说服基础处理小数属性时使用我的模型绑定器的类。
The reason I need this: In one of my controllers I want to bind all Decimal values in a different way than the rest of my application. I do not want to register a Model Binder in Global.asax (via ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
)
I have tried deriving from the DefaultModelBinder
class and override its BindProperty
method, but that only works for the model instance's immediate (not nested) Decimal properties.
I have the following example to demonstrate my problem:
namespace ModelBinderTest.Controllers
{
public class Model
{
public decimal Decimal { get; set; }
public DecimalContainer DecimalContainer { get; set; }
}
public class DecimalContainer
{
public decimal DecimalNested { get; set; }
}
public class DecimalModelBinder : DefaultModelBinder
{
protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor)
{
if (propertyDescriptor.PropertyType == typeof (decimal))
{
propertyDescriptor.SetValue(bindingContext.Model, 999M);
return;
}
base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
}
}
public class TestController : Controller
{
public ActionResult Index()
{
Model model = new Model();
return View(model);
}
[HttpPost]
public ActionResult Index([ModelBinder(typeof(DecimalModelBinder))] Model model)
{
return View(model);
}
}
}
This solution only sets the Model
's Decimal
property to 999, but doesn't do anything to DecimalContainer
's DecimalNested
property. I realize this is because base.BindProperty
is called in my DecimalModelBinder
's BindProperty
override, but I don't know how to convince the base class to use my Model Binder when dealing with decimal properties.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以在
Application_Start
中无条件应用模型绑定器:然后有一个自定义授权过滤器(是的,授权过滤器,因为它在模型绑定器之前运行),它将向 HttpContext 注入一些稍后可能会被使用的值。由模型绑定器使用:
然后在模型绑定器中测试 HttpContext 在应用它之前是否包含自定义值:
现在剩下的就是使用自定义过滤器装饰控制器操作以启用十进制绑定器:
You could apply the model binder unconditionally in your
Application_Start
:and then have a custom authorization filter (yes, authorization filter as it runs before the model binder) that will inject into the HttpContext some value that could later be used by the model binder:
and then in your model binder test if the HttpContext contains the custom value befoire applying it:
Now all that's left is to decorate your controller action with the custom filter to enable the decimal binder: