自定义模型绑定问题
在我的MVC 3解决方案中,我希望将查询字符串中的所有Id都加密。要解密的URL我从DefaultModelBinder继承和overrided BindProperty方法:自定义模型绑定问题
public class CryptedIdBinder : DefaultModelBinder
{
protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor)
{
if (propertyDescriptor.Name.ToLower() == "id")
{
propertyDescriptor.SetValue(bindingContext.Model, CryptoHelper.Decrypt(controllerContext.HttpContext.Request.Form["id"]));
return;
}
base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
return;
}
之后,我设置在Global.asax的新DefaultBinder上的Application_Start:
System.Web.Mvc.ModelBinders.Binders.DefaultBinder = new CryptedIdBinder();
我没有从IModelBinder继承,因为我想更改绑定逻辑只有解决方案中的id字段。
问题是BindProperty方法从不被调用。我错了什么?
PS。为了确保我打电话至少BindModel方法我将我的定制绑定在这个代码的和平,它是由调试器击中:
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
return base.BindModel(controllerContext, bindingContext);
}
如果您的机型没有,当然标识符属性BindProperty不会被调用。因为它调用了模型属性。如果我理解你的问题,你需要的是转换每个Id命名查询字符串参数。在这种情况下,您需要自定义值提供程序而不是模型绑定器。这是关于价值提供者的good article。而且它很容易写一个:
public class MyValueProviderFacotry : ValueProviderFactory
{
public override IValueProvider GetValueProvider(ControllerContext controllerContext)
{
return new MyValueProvider(controllerContext);
}
}
public class MyValueProvider : IValueProvider
{
private ControllerContext controllerContext;
public MyValueProvider(ControllerContext controllerContext)
{
this.controllerContext = controllerContext;
}
public bool ContainsPrefix(string prefix)
{
return true;
}
public ValueProviderResult GetValue(string key)
{
if (key.ToLower() == "id")
{
var originalValue = controllerContext.HttpContext.Request.QueryString[key];
var transformedValue = CryptoHelper.Decrypt(orignalValue);
var result = new ValueProviderResult(transformedValue,originalValue,CultureInfo.CurrentCulture);
return result;
}
return null;
}
}
在Global.asax中:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
ValueProviderFactories.Factories.Insert(4, new MyValueProviderFacotry()); //Its need to be inserted before the QueryStringValueProviderFactory
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
中非常感谢您的答复。它看起来像这是我正在寻找的东西。我会在早上尝试这个 –
这个作品几乎很棒。我必须做的唯一事情就是实现ContainsPrefix(所以它确实返回值,指示是否需要搜索值),并将它放在QueryStringValueProviderFactory之前,但不放在RouteValueProviderFactory之前。再次感谢! –
你可以张贴一些示例模型代码?也许DefaultModelBinder过滤了你的一些属性... – nemesv
对不起,我没有听到你的想法。它不是一个全球活页夹,它应该适用于所有型号?此Id参数未在模型中定义 - 它位于默认路线 –