[英]C# MVC: When to use a specific (non-default) ModelBinder?
据我了解,默认模型联编程序能够
<input type="text" name="myType.property1" value="John Doe" /> <input type="text" name="myType.property2" value="22" />
变成:
[AcceptVerbs(HttpVerbs.Post)] public ActionResult SomeAction(MyType myType) { // This will be "John Doe" String someName = myType.property1; // This will be 22 Int32 someNumber = myType.property2; // // irrelevant magic }
在哪种情况下,我将使用非默认模型联编程序? 我想不出一个名称与类属性名称不同的名称。 请举例说明。
谢谢!
在您的MyType
例如没有默认构造函数的情况下(默认modelbinder需要默认构造函数)。
如果您使用工厂方法模式创建新对象,则可能会发生这种情况(非常简单的示例只是为了说明;-):
public class MyType
{
private MyType() // prevent direct creation through default constructor
{
}
public static MyType CreateNewMyType()
{
return new MyType();
}
}
然后,您将必须实现一个自定义模型绑定程序,该模型调用工厂方法CreateNewMyType()
而不是通过反射创建新的MyType
:
public class MyTypeBinder : DefaultModelBinder
{
protected override object CreateModel(ControllerContext controllerContext,
ModelBindingContext bindingContext,
Type modelType)
{
return MyType.CreateNewMyType();
}
}
另外,如果您对默认Modelbinder的当前功能或实现不满意,则可以轻松地将其替换为自己的实现。
Scott Hanselman有一个针对自定义模型活页夹的
简单
案例研究。
这篇文章的要点不是用默认绑定无法以其他方式完成他想做的事情,而是
他正在尝试
让他重新使用将为他完成工作的代码。
考虑一个称为TimeInterval的自定义类型,该类型存储为双精度型,但显示为hh.mm.ss.ffffff ,其中ffffff是小数秒。 使用自定义绑定,可以向绑定程序显示如何正确解析和显示这些数字,而不必在控制器中编写自定义代码。
// This class implements a custom data type for data binding.
public class TimeInterval
{
double _value;
public TimeInterval(string value)
{
// Extension method parses string value to double.
_value = value.ToSeconds();
}
public TimeInterval(double value)
{
_value = value;
}
public string GetText()
{
// Extension method formats double value as time string.
return _value.ToTimeString();
}
public double? GetValue()
{
return _value;
}
}
// This class implements custom binding for the TimeInterval custom type.
// It is registered in Global.asax
public class TimeIntervalBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
string value = GetAttemptedValue(bindingContext);
if (value == "")
return null;
return new TimeInterval(value);
}
private static string GetAttemptedValue(ModelBindingContext context)
{
ValueProviderResult value = context.ValueProvider[context.ModelName];
return value.AttemptedValue ?? string.Empty;
}
}
// in Global.asax:
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
ModelBinders.Binders.Add(typeof(TimeInterval), new TimeIntervalBinder());
}
现在,对于新的自定义类型,绑定会自动发生。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.