C # MVC: Когда использовать определенный (не по умолчанию) ModelBinder? - PullRequest
1 голос
/ 10 июня 2009

Насколько я понимаю, модель подшивки по умолчанию способна превращаться

</p> <pre><code><input type="text" name="myType.property1" value="John Doe" /> <input type="text" name="myType.property2" value="22" />

в

</p> <pre><code>[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 }

В каком сценарии я бы использовал связыватель модели не по умолчанию? Я не могу придумать причину не называть входные данные HTML иначе, чем имена свойств классов. Поясните, пожалуйста, с примером.

Спасибо!

Ответы [ 3 ]

3 голосов
/ 11 июня 2009

В сценарии, например, у вашего MyType нет конструктора по умолчанию (для связующего устройства по умолчанию требуется конструктор по умолчанию).
Это может произойти, если вы используете шаблон фабричного метода для создания нового объекта (очень простой пример только для иллюстрации ;-):

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();
    }
}

Также, если вас не устраивает текущая функциональность или реализация связующего устройства по умолчанию, вы можете легко заменить его на собственную реализацию.

2 голосов
/ 11 июня 2009

Рассмотрим пользовательский тип с именем TimeInterval, который хранится как double, но отображается как 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());
}

Теперь привязка происходит автоматически для нового пользовательского типа.

2 голосов
/ 11 июня 2009

У Скотта Хансельмана есть a простой пример использования связующего для пользовательской модели.

Суть поста не в том, что то, что он пытается сделать, нельзя сделать другими способами с привязкой по умолчанию, а в том, что он пытается , что позволяет ему повторно использовать код, который будет делать работа для него.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...