Класс ASP.Net MVC ModelBindingContext - как заполняются значения модели? - PullRequest
8 голосов
/ 19 августа 2010

Я немного ломаю голову над тем, как связующие модели работают в ASP.Net MVC.

Если говорить точнее, метод BindModel () имеет параметр ModelBindingContext, который содержит имя и тип модели, но я не понимаю, как ModelBindingContext получает эти значения.

Модель MVC должна быть заполнена из опубликованных значений формы или параметров строки запроса или других источников данных.Но какой механизм определяет тип модели, передаваемый ModelBindingContext, и как один тип модели выбирается из другого типа модели, даже по сравнению, скажем, с простым списком, содержащим отдельные опубликованные значения?

Мне просто кажется, что ModelBindingContext "знает" тип модели, которую он передает, и я не уверен, откуда она берется или рабочий процесс, связанный с ее заполнением.

Ответы [ 3 ]

12 голосов
/ 22 августа 2010

Интересный вопрос.Вот простой обзор того, что делает MVC.Все это обрабатывается классом ControllerActionInovker.Это не в определенном порядке, но близко.

  1. ControllerActionInovker определяет тип параметра посредством отражения.
  2. Следующие ValueProviders создаются из формы запроса HttpContext, Route, QueryString и т. Д.свойства.Вы также можете предоставить своих собственных поставщиков значений.
  3. Эти ValueProviders передаются в ModelBindingContext через коллекцию, которая действует как виртуальный ValueProvider.
  4. Затем ControllerActionInovker ищет ModelBinder для определенного типа.Если он не находит его, по умолчанию используется встроенный DefaultModelBinder.
  5. В большинстве случаев используется DefaultModelBinder.Его задача - создать модель и использовать ValueProviders для связывания свойств со значениями, используя имена свойств модели в качестве ключа.Когда ValueProviders имеют значение, они возвращают объект ValueProviderResult, который отвечает за преобразование типов.

Вы можете сами убедиться в этом в ASP.net MVC-источнике, расположенном по адресу codeplex.com .Найдите класс ControllerActionInvoker и метод GetParameterValue.

3 голосов
/ 19 августа 2010

ModelBindingContext «знает» тип модели, которую он передает, потому что вы должны либо:

  • Добавить атрибут ModelBinder в вашу модель
  • ЗарегистрироватьсяModelBinder с вашей моделью с использованием метода ModelBinders.Binders.Add ().

Пример атрибута ModelBinder:

[ModelBinder(typeof(ContactBinder))]
public class Contact { ... }

ПримерModelBinders.Binders.Add ():

void Application_Start()
{
  ModelBinders.Binders[typeof(Contact)] = new ContactBinder();
}

Если вы зарегистрировали свой ModelBinder и внедрили метод BindModel:

public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { ... }
  1. Запрос ModelBindingContext.ModelType равен вашей модели, например,

    if (bindingContext.ModelType == typeof(Contact)) { ... }
    
  2. Повторно гидратируйте вашу модель из свойства ModelBindingContext.ValueProvider, чтобы получить экземпляры ValueProviderResult, которые представляют данные из сообщений формы, данные маршрута и строка запроса, например,

    bindingContext.ValueProvider["Name"].AttemptedValue;
    

Следующие книги использовались ASP.NET MVC 2 в действии и ASP.NET MVC1,0 быстро

1 голос
/ 14 июня 2011

Я вижу, что ControllerActionInvoker использует отражение для получения типа параметра, затем он проверяет, назначен ли какой-либо ModelBinder для работы с этим типом, если это так, он создает экземпляр этого ModelBinder и передает ему BindingContext, который будет содержать (модельобъект, имя модели, тип модели, фильтр свойств) для этого объекта типа параметра и коллекция поставщиков значений (ModelBindingContext.ValueProvider) всех других поставщиков значений (Form, Query String и т. д.), выступающих в качестве одного большого поставщика виртуальных значений.

Затем ModelBinder сам использует отражение для получения всех имен свойств для типа, назначенного ему для привязки, и рекурсивно запускается для всех поставщиков значений в (ModelBindingContext.ValueProvider) и ищет имена свойств в этих поставщиках значений, связывая ихзначения, для которых имена (взятые из клиента) соответствуют именам свойств типа, когда они соответствуют поставщику значений, возвращается объект ValueProviderResult, содержащий имя и значение для соответствующегоСвойство по модели.

...