Site visitors are conditioned to believe that hitting the browser’s refresh button will simply refresh the page. In reality the browser re-issues the last Http Request. That’s fine if it was just a GET Request which typically only loads a page, but if the request was a POST Request which typically updates values on the server that could result in undesirable results such as a duplicate order.
Fortunately there is a very simple pattern to protect against a re-POST due to page refresh – the PRG (POST-Redirect-GET) pattern. This is very easily implemented in an MVC web framework such as ASP.NET MVC. The controller which handles the POST Request performs the necessary processing and then redirects to another controller using a GET Request which then renders the final view to be returned to the site user.
A simple implementation is shown below. Here the Order controller accepts the POST Request from the user’s browser. If the ItemOrder object has no validation errors some processing is performed and then the ASP.NET MVC RedirectToAction method is called which issues a GET Request and passes the order id to the OrderSuccess controller. The OrderSuccess controller passes the OrderSuccess view (ie page) to the user. Now, if the user refreshes the browser a GET Request for the OrderSuccess page is issued and no duplicate POST is made.
[HttpPost] public ActionResult Order(ItemOrder itemOrder) { if (ModelState.IsValid) { //do processing return RedirectToAction("OrderSuccess", new { id = itemOrder.Id }) } return View(model); //if there is an error in the model the page is returned } public ViewResult OrderSuccess(int id) { return View(id); }