Introduction
I was working on some sensitive ASP.NET MVC software and I didn’t want to give the user a chance to accidentally refresh the page and resubmit the data again. I read a couple of articles online but sometimes they was a little bit confusing on their solution. I was thinking about something simple.
Background
My solution is based on using session as container to pass the message and to detect if POST
method is called before.
Using the Code
In most of the cases, there are two methods - one that creates and calls the view (GET
request) and one that manages the POST
request:
[HttpGet]
public ActionResult Index()
{
if((String)Session["MSG"]!=null)
{
ViewData["Done"] = (String)Session["MSG"];
}
Session.Remove("MSG");
return View("Index");
}
[HttpPost]
public ActionResult Index(SimpleViewModel s)
{
Debug.WriteLine(s.name);
Session.Add("MSG", "Call DONE SUCCESS");
return RedirectToAction("Index");
}
The first method manages the get
request and checks if there is any message in the session and if there is no message, this means that the method is NOT called from the POST
method. If there is any message in the session, then this mean that the method is called from the POST
method and the index should show the message.
On the other hand, in the POST
method, you initialize the message. The problem with the command below is the
RedirectToAction("Index");
fact that all the local data are deleted because the contructor is called again but it eliminates the chance for the user to accidentally resubmit the data. If you use the command:
return Index();
the context variables are stored so you don't care any more about passing the messages or other object but the user can resubmit the data with refresh.
View
<h2>Index</h2>
@using (Html.BeginForm("Index","Home",FormMethod.Post))
@Html.TextBoxFor(x => x.name);
if(ViewData["Done"]==null)
{
WriteLiteral("No Message Found");
}
else
{
Write(ViewData["Done"]);
}
<input type="submit" value="send" />
}