Я на 100% согласен с общим ответом RedFilter, но хотел опубликовать соответствующий код для ASP.NET MVC, в частности.
Вы можете использовать шаблон Post / Redirect / Get (PRG) для решения проблемы двойной обратной передачи.
Вот графическая иллюстрация проблемы:
Что происходит, когда пользователь нажимает кнопку обновления, браузер пытается повторно отправить последний запрос, который он сделал. Если последним запросом была запись, браузер попытается это сделать.
Большинство браузеров знают, что это обычно не то, что пользователь хочет сделать, поэтому автоматически спросят:
Хром -
Страница, которую вы ищете, использовала введенную вами информацию.
Возврат на эту страницу может привести к тому, что любое предпринятое вами действие будет повторено.
Вы хотите продолжить?
Firefox - Чтобы отобразить эту страницу, Firefox должен отправить информацию, которая будет повторять любое действие (например, поиск или подтверждение заказа), которое было выполнено ранее.
Safari -
Вы уверены, что хотите отправить форму еще раз?
Чтобы снова открыть эту страницу, Safari должен повторно отправить форму. Это может привести к повторным покупкам, комментариям или другим действиям.
Internet Explorer -
Чтобы снова отобразить веб-страницу, веб-браузер должен
повторно отправьте информацию, которую вы ранее отправили.
Если вы совершали покупку, нажмите «Отмена», чтобы
избежать дублирования транзакции. В противном случае нажмите «Повторить», чтобы отобразить
снова веб-страница.
Но шаблон PRG помогает избежать этого в целом, посылая клиенту сообщение о перенаправлении, поэтому, когда страница наконец появляется, последний запрос, выполненный браузером, был запросом GET для нового ресурса.
Вот отличная статья по PRG , которая предоставляет реализацию шаблона для MVC. Важно отметить, что вы хотите прибегать к перенаправлению только тогда, когда на сервере выполняется не идемпотентное действие. Другими словами, если у вас есть действительная модель и вы действительно сохранили данные каким-либо образом, важно убедиться, что запрос не был случайно отправлен дважды. Но если модель недействительна, текущая страница и модель должны быть возвращены, чтобы пользователь мог внести любые необходимые изменения.
Вот пример контроллера:
[HttpGet]
public ActionResult Edit(int id) {
var model = new EditModel();
//...
return View(model);
}
[HttpPost]
public ActionResult Edit(EditModel model) {
if (ModelState.IsValid) {
product = repository.SaveOrUpdate(model);
return RedirectToAction("Details", new { id = product.Id });
}
return View(model);
}
[HttpGet]
public ActionResult Details(int id) {
var model = new DetailModel();
//...
return View(model);
}