h3mm3's blog

Stories from behind the keyboard

  • RSS
  • Twitter

The Post/Redirect/Get (PRG) pattern is a practical remedy against the “refresh-your-page-after-you-sent-form-data” troubles. In this article I present a simple way to implement this pattern in a WebMatrix website.

The pattern

Simply put, in the PRG pattern, the server, after receiving data from a form page P1, answers with a REDIRECT message to a different page (P2). Doing so, the browser will REQUEST the page P2 and if the user will try to refresh the page (e.g. hitting F5) the browser will simply reload the page P2, without sending any more data to the server.

The Post/Redirect/Get pattern

Image courtesy Wikimedia Common. Original URL: [http://en.wikipedia.org/wiki/File:PostRedirectGet_DoubleSubmitSolution.png]

The solution

In order to keep things clear and simple, my solution is built around three files:

  • A form page (form.cshtml)
  • A server-side page that collects data from the form page (formaction.cshtml)
  • An answer page (result.cshtml)

In form.cshtml we write a simple HTML form, like this:


<body>
   <h1>Enter something</h1>
   <form action="formaction" method="post">
     <input type="text" name="textbox"/>
    <input type="submit"/>
   </form>
</body>

Notice how the action attribute of the form points to the formaction.cshtml page (look ma: no extension! ...more details here).

In formaction.cshtml we read form data from the Request, validate them and finally answers the browser with a REDIRECT, putting an exit code directly inside the URL:

@* A pure server-side page *@
@{
    var textvalue = Request["textbox"];
    
    if (textvalue.IsEmpty()) {
        Response.Redirect("result/ko");
    } else {
        Response.Redirect("result/ok");
    }
}

The last page is result.cshtml. Here we read the exit code from the request (it is in the UrlData List) and write in the page accordingly.

@* The answer page *@
@{
    var result = UrlData[0];
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
        @switch (result){
            case "ok":
                <text>All right!</text>
                break;
            case "ko":
                <text>Something left!</text>
                break;
            default:
                <text>Dunno...</text>
                break;
        }
        Back to your <a href='@Href("~/form")'>form</a>.
    </body>
</html>

Happy programming!

No comments: