Подтвердить что ты не робот

Как работает метод ASP.NET MVC UpdateModel()?

Я работаю над своим первым приложением .NET MVC и использую учебник NerdDinner в качестве ориентира. Один момент, который меня интригует на данный момент, - это метод UpdateModel(). (Я не люблю использовать вещи, которые я действительно не понимаю.)

Взято из Учебник NerdDinner -

//
// POST: /Dinners/Edit/2

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection formValues) {

    Dinner dinner = dinnerRepository.GetDinner(id);

    UpdateModel(dinner);

    dinnerRepository.Save();

    return RedirectToAction("Details", new { id = dinner.DinnerID });
}

Мой главный вопрос: как UpdateModel() получить доступ к formValues, переданным в методе Edit? Почему коллекция не передается явно как параметр метода?

4b9b3361

Ответ 1

UpdateModel() - это вспомогательный метод контроллера, который пытается связать связку различных источников входных данных (данные HTTP POST, поступающие из значений View, QueryString, переменных сеанса/файлов cookie и т.д.) в явный объект модели, который вы указываете как параметр. По сути, это только для привязки модели.

Если вы выражаете входные параметры для своего Action как сильно типизированной модели (например, View Model), вы уже сделали все шаги, которые выполняются за кулисами при вызове метода UpdateModel(). Если вы извлекаете объект из DataContext и изменяете его свойства, SaveChanges() - это все, что вам нужно, чтобы вернуть обновления в базу данных (в этом случае Save()).

Пример:

//
// POST: /Dinners/Edit/2

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(DinnerViewModel incoming) {

    var dinner = dinnerRepository.GetDinner(incoming.DinnerID);
    dinner.Description = incoming.Description;
    dinnerRepository.Save();

    return RedirectToAction("Details", new { id = incoming.DinnerID });
}

Однако используется прецедент для использования UpdateModel() с сильно типизированной моделью: когда вы проходите в сильно типизированной модели и хотите, чтобы ее значения были непосредственно заменены значениями объект из базы данных (при условии, что все они названы и набраны одинаково). В этом случае вы будете извлекать объект, использовать UpdateModel() на нем, и его операция привязки модели будет вытягивать любые одинаково названные и типизированные свойства от строго типизированного объекта к извлеченному объекту. Другими словами, он будет выполнять отражение для вас.

Итак, как и в вашем примере, если вы хотите, чтобы все свойства обновлялись без указания того, что нужно обновлять, а ваша сильно типизированная модель и модель базы данных имеют похожие свойства, вы все равно захотите использовать UpdateModel(), чтобы воспользоваться преимуществами отражение.

Пример:

//
// POST: /Dinners/Edit/2

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(DinnerViewModel incoming) {

    var dinner = dinnerRepository.GetDinner(incoming.DinnerID);
    UpdateModel(dinner);
    dinnerRepository.Save();

    return RedirectToAction("Details", new { id = incoming.DinnerID });
}

Единственное преимущество здесь (с использованием объекта FormCollection) заключается в том, что у вас будет доступ ко всем другим свойствам строго типизированного объекта (как показано в файле incoming.DinnerID).

Заключение: если вы переводите сильно типизированный объект в производный объект, возможно, проще всего использовать UpdateModel(). Однако это в значительной степени не нужно, если вы просто обновляете несколько свойств производного объекта. Кроме того, имейте в виду, что использование Entity Framework (вместо чего-то вроде Linq to SQL) делает все это спорным, поскольку оно может связывать сильно типизированные объекты и производные объекты своими собственными методами.

Ответ 2

Он проверяет все входы HttpRequest, такие как Form, QueryString, Cookies и Server. Я думаю в этом порядке.