繁体   English   中英

C#MVC:何时使用特定的(非默认)ModelBinder?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM