Что, собственно, делает modelbinder делать? Как использовать его эффективно?


Я что-то исследовал и наткнулся на этот пост в блоге buildstarted.com о модельных связующих. Это на самом деле работает чертовски хорошо для моих целей, но я не уверен точно, что происходит за кулисами. Что я сделал, это создать пользовательский ModelBinder называется USerModelBinder:

public class UserModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        ValueProviderResult value = bindingContext.ValueProvider.GetValue("id");
        MyEntities db = new MyEntities();
        User user = db.Users.SingleOrDefault(u => u.UserName == value.AttemptedValue);
        return user;
    }
}

Тогда в моем Global.asax.cs у меня есть:

ModelBinders.Binders.Add(typeof(User), new UserModelBinder());

Мое понимание заключается в том, что использование связывателя моделей позволяет мне не использовать следующие строки в каждом действии контроллера, которое включает пользователь". Поэтому вместо того, чтобы передать "id" действию, modelbinder перехватывает идентификатор, выбирает правильный "элемент"(пользователь в моем случае) и направляет его в действие для обработки.

        MyEntities db = new MyEntities();
        User user = db.Users.SingleOrDefault(u => u.UserName == value.AttemptedValue);

Я также попытался использовать аннотацию в своем пользовательском классе вместо использования строки в Global.асакс.cs:

[ModelBinder(typeof(UserModelBinder))]
public partial class User
{
}
Я не ищу 30-страничную белую бумагу, но я понятия не имею, как модель binder делает то, что она делает. Я просто хочу понять, что происходит с момента подачи запроса до момента его подачи. сервируемый. Все эти вещи "просто работают" для меня неприемлемы, лол. Кроме того, есть ли разница между использованием аннотации и ее добавлением в Global?асакс.КС? Они, кажется, работают одинаково в моем тестировании, но есть ли какие-то готы?
2 4

2 ответа:

Обычно связыватель моделей (в MVC) смотрит на метод действия и видит, что ему требуется (например, типы объектов). Затем он пытается найти значения из HTTP-запроса (значения в форме HTTP, QueryString, Json и, возможно, в других местах, таких как файлы cookie и т. д. использование ValueProviders). Затем он создает новый объект с полученными параметрами.

IMO то, что вы сделали, на самом деле не является "привязкой модели". В том смысле, что вы только что прочитали идентификатор и извлекли объект из ДБ.

Пример обычной привязки модели:

// class
public class SomeClass
{
    public int PropA {get;set;}
    public string PropB {get;set;}
}

// action

public ActionResult AddSomeClass(SomeClass classToBind)
{
  // implementation
}

// pseudo html

      <form action="">
       <input name="PropA" type="text" />
       <input name="PropB" type="text" />
      </form>

Если вы размещаете форму, содержащую правильные значения (допустим, вы размещаете форму с PropA и PropB), связыватель модели может определить, что вы отправили эти значения в форме, и построить объект SomeClass.

Если вы действительно хотите создать реальный рабочий пример, вы должны использовать строго типизированное представление и использовать редактор HtmlHelper (или EditorForModel) для создания всех правильных имен, которые нужны MVC.

--

Для ссылка MVC по умолчанию связыватель является DefaultModelBinder, и некоторые (есть больше, вы можете посмотреть вокруг в системе.Сеть.Пространство имен Mvc) ValueProviders, которые он использует по умолчанию, являются FormValueProvider и QueryStringValueProvider

Итак, как я уже сказал, в основном это работает так: связыватель модели по умолчанию читает модель, которую получает действие (скажем, SomeClass в Примере), читает, какие значения он может прочитать (скажем, PropA и PropB)и запрашивает у ValueProviders правильные значения для свойств.

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

A ModelBinder просматривает аргументы сигнатуры метода выбранного действия Controller, а затем преобразует значения из ValueProviders в эти аргументы.

Это происходит, когда ControllerActionInvoker вызывает действие, связанное с ControllerContext, потому что метод Controller Execute() сказал ему.

Подробнее о ASP.NET процесс выполнения MVC, см. понимание процесса выполнения приложения MVC