Получение после перенаправления в ASP.NET MVC и проверка правильности URL - PullRequest
17 голосов
/ 04 апреля 2011

У меня есть спокойный URL для действия по редактированию страницы.Это реализовано на контроллере как метод Edit, который принимает запросы GET, и метод Edit, который принимает запросы POST.

Это означает, что вы можете посетить URL-адрес редактирования и отобразить форму для GET или сохранитьформа для POST.

[HttpGet]
public ActionResult Edit(int id) {
    ...
}

[HttpPost]
public ActionResult Edit(EditModel model) {
    ...
}

Шаблон Post-Redirect-Get (PRG) выглядит довольно черно-белым, потому что он по существу перенаправляет каждый POST обратно в действие GET.Однако мне нужно убедиться, что это правильно.

Мой план заключается в том, что в действии POST, если модель действительна, я буду использовать шаблон Post-Redirect-Get для отправки пользователюв разумное место (возможно, действие «Индекс» или «Сведения»).

Однако, если существует проблема с проверкой модели, я все равно хочу просто отобразить представление.Я не хочу перенаправлять пользователя, потому что это означает вставку модели и ModelState во временные данные и перенаправление в действие GET, а затем добавление логики в действие GET для обработки временных данных.Я мог бы избежать всего этого, просто отображая представление.

Да, если пользователь нажмет F5, он повторно отправит форму, и ему будет представлено «предупреждение о повторной передаче», но затем на той же странице (прося их исправить ошибки валидации).Тем не менее, маловероятно, что они попадут в F5, и также нет опасности двойной отправки, так как форма просто не пройдет проверку еще раз.

Если проверка пройдена, пользователь будет перенаправлен, и онибудет защищен от двойных представлений.

Поэтому я должен внедрить дополнительный код и данные заполнения во временные данные, чтобы строго следовать шаблону PRG, или более разумно использовать шаблон PRG, когда форма действительна иданные хранятся?

Ответы [ 3 ]

21 голосов
/ 04 апреля 2011

Переадресацию следует выполнять только в том случае, если информация в форме верна; в случае ошибок отправки верните представление из того же метода Edit.

При этом совместим с PRG, поскольку, если ваша модель недействительна, вы не разрешаете вносить какие-либо изменения в состояние объектов на сервере. PRG предназначен в первую очередь для предотвращения нескольких сообщений, которые могут непредсказуемым образом изменить состояние объектов сервера (например, бизнес-объектов, таблиц базы данных и т. Д.); однако в вашем примере проверки пользователь может выполнить повторную отправку столько раз, сколько пожелает, и он всегда будет отправлен обратно в исходное представление с ошибками проверки - на сервере ничего не изменится. Таким образом, вы правы: перенаправлять вызовы можно только в том случае, если ваша модель прошла проверку на уровне представления.

10 голосов
/ 04 апреля 2011

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

Самый простой способ справиться с этим сценарием - использовать фильтры действий для экспорта состояния модели в сеанс (до перенаправления), а затем импортировать состояние модели (до выполнения нового действия). Кази Манзур Рашид имеет несколько отличных постов в блоге ( Часть 1 Часть 2 ) о лучших практиках в ASP.NET MVC.Они довольно старые, но многие из советов там еще очень применимы.Совет № 13 в первой статье - это именно то, что вам нужно.

0 голосов
/ 13 июня 2013

PRG - это то, что нужно сделать.

Вы выполняете POST для действия, и если состояние модели недопустимо, вы просто «экспортируете» свои данные состояния модели в переменную и перенаправляете в действие get.

Это дает преимущество по сравнению с принятым ответом: вам не нужно переписывать код в действии [Post], чтобы воссоздать представление.

в действии get, которое вы загружаете из ModelState, экспортированного изпост один.

TempData - отличное место для этого, код будет выглядеть примерно так:

[HttpGet]
public ActionResult Edit(int id) {
    // import model state from tempdata
    ...
}

[HttpPost]
public ActionResult Edit(EditModel model) {
    // if modelstate is invalid
    // save modelstate in tempdata
    // redirect to Edit/{id}
    // else 
    ...
    RedirectToAction("List")
}

это можно автоматизировать с помощью AttributeFilters, там отлично post create @ ben-foster здесь:

Автоматическая проверка состояния модели

...