Я не "получаю" ModelBinder в MVC 2 - PullRequest
2 голосов
/ 15 июля 2010

Я понимаю, что ModelBinder - это хорошее место для выполнения работы над запросом, так что вы держите этот тип кода вне контроллера. Работа со значениями формы будет примером. Это, кажется, имеет смысл, однако, я унаследовал приложение, которое использует Custom Binder, и я просто не могу понять, как и почему он работает.

Сам механизм связывания существует, чтобы иметь дело только с объектами 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;
    }
}

Теперь из-за пошагового выполнения кода, который я знаю, этот Binder вызывается только тогда, когда я отправляю данные обратно на сервер, который включает определенную модель, у которой есть свойство TimeZoneInfo. Мои предположения:

  • Среда выполнения «знает» обо всех моделях и вызывает пользовательский связыватель, только когда находит свойство того же типа, что и тот, который был передан в связыватель.
  • Причина, по которой это делается, заключается в том, что тип TimeZoneInfo является сложным типом и, следовательно, не может быть неявно преобразован в строку (данные POST)

Это правильное понимание данного конкретного случая или я что-то упустил?

Спасибо!

1 Ответ

1 голос
/ 16 июля 2010

Вы близки ...

Связыватель модели учитывает все данные из данных формы запроса, строки запроса URL-адреса и параметров маршрутизации.Привязка будет пытаться привязать аргументы метода действия и любые открытые свойства модели, для которых определены как get, так и set.Это делается с учетом имени параметра и / или открытого свойства.

Поскольку все входные источники имеют формат имени-значения, имена совпадают.Например, если есть параметр маршрутизации «id», а ваш метод действия имеет аргумент «id» в своей сигнатуре, средство связывания свяжет параметр маршрутизации с этим аргументом метода действия.Если есть поле формы страны и модель с общедоступным свойством страны, средство связывания модели попытается привязать поле формы к модели.И т.д.

Привязка учитывает тип свойства при привязке.Связыватель модели по умолчанию знает, как связать со скалярными свойствами (int, decimal, DateTime и т. Д.).Он также может связываться со списком (формат ключа MyList [0]) или со сложным типом, который, в свою очередь, предоставляет дочерние свойства (например, формат ключа Rectangle.Width).

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

Обратите внимание, что ModelBinder работаетв сочетании со словарем ModelState.Важно, чтобы неверный пользовательский ввод сохранялся, даже если он не может быть преобразован в целевой тип.В этом случае в словарь ModelState добавляется ошибка, а необработанное значение входного параметра сохраняется, чтобы его можно было включить в повторное отображение формы с ошибками проверки.

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