我知道ModelBinder是处理请求的好地方,这样您就可以将这种类型的代码排除在控制器之外。使用表单值就是一个例子。然而,我继承了一个使用自定义绑定器的应用程序,但我似乎不知道它是如何工作的或为什么工作。
绑定器本身只处理TimeZoneInfo对象,因为它们(时区)在应用程序中使用,因此它在全局的Application_Start方法中注册,如下所示:
binders.Add(new System.Collections.Generic.KeyValuePair<Type, IModelBinder>(typeof(TimeZoneInfo), new TimeZoneInfoModelBinder()));其中粘合剂是ModelBinderDictionary类型的。然后,活页夹本身看起来如下:
public class TimeZoneInfoModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException("bindingContext");
}
string tzId = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue;
try
{
return TimeZoneInfo.FindSystemTimeZoneById(tzId);
}
catch (Exception ex)
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex);
}
return null;
}
}现在,从代码开始,我知道只有当我将数据回发到涉及特定模型的服务器时才会调用这个绑定器,该服务器上有一个TimeZoneInfo属性。我的假设是:
这是正确理解这一特殊情况,还是我遗漏了什么?
谢谢!
发布于 2010-07-16 09:28:11
你很接近..。
模型绑定器考虑来自请求的表单数据、URL查询字符串和路由参数的所有数据。绑定器将尝试绑定到action方法的参数以及模型中具有get和set定义的任何公共属性。这是通过考虑参数和/或公共属性的名称来完成的。
由于所有输入源都是以名称-值格式表示的,所以名称是匹配的。例如,如果有一个"id“路由参数,而您的操作方法的签名中有一个"id”参数,则绑定器将将路由参数绑定到该操作方法参数。如果存在国家表单字段和具有公共国家属性的模型,则模型绑定器将尝试将表单字段绑定到模型。等。
绑定器在绑定时考虑属性的类型。默认的模型绑定器知道如何绑定到标量属性(int、十进制、DateTime等)。它还可以绑定到列表(键格式MyList)或复杂类型,后者反过来公开子属性(例如,键格式Rectangle.Width)。
您发布的示例增加了绑定到TimeZoneInfo对象的能力。之所以调用该绑定器,是因为表单参数、查询参数或路由参数的名称与公开返回TimeZoneInfo对象的getter和setter的模型上的公共属性的名称匹配。
注意,ModelBinder与ModelState字典协同工作。即使不能将无效的用户输入转换为目标类型,也必须保留无效的用户输入。在这种情况下,将错误添加到ModelState字典中,并保留输入参数的原始值,以便在表单的重呈现中包含验证错误。
https://stackoverflow.com/questions/3249998
复制相似问题