Что, собственно, делает 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 ответа:
Обычно связыватель моделей (в 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
, а затем преобразует значения изValueProvider
s в эти аргументы.Это происходит, когда
ControllerActionInvoker
вызывает действие, связанное сControllerContext
, потому что методController
Execute()
сказал ему.Подробнее о ASP.NET процесс выполнения MVC, см. понимание процесса выполнения приложения MVC