Sunday, May 26, 2013

How to Use PRG Pattern with ASP.net MVC 4 ?

What is the PRG Pattern ?

  • PRG stands for "Post/Redirect/Get"
  • Instead of returning an HTML page directly,
  • The POST operation returns a redirection command (using the HTTP 303 response code (sometimes 302) together with the HTTP "Location" response header),
  • Instructing the browser to load a different page using an HTTP GET request
  • The result page can then safely be bookmarked or reloaded without unexpected side effects

How to Explain this by using an Example ?

  • Here I'm going to use User Registration function as an example
  • If the Registration attempt is Successful, the user should be redirected to his Home page
  • Otherwise they should be redirected back to the Registration page

Image 1 : Shows Action Methods Interaction When do Registration

Shows Action Methods Interaction When do Registration


AccountController.cs        
        
Code for the Register Action Method (Get) for Displaying Register View is as below

Complete project        /// <summary>
        /// for displaying Register View
        /// </summary>
        [HttpGet]
        [AllowAnonymous]
        public ActionResult Register()
        {
            return View();
              }


      Image 2 : Register View

Register View

        
Code for the Register Action Method (Post) for Processing the Registration and Shows Register Page again is as below

        /// <summary>
        /// for Registering the User
        /// </summary>
        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public ActionResult Register(RegisterModel model)
        {
          if (ModelState.IsValid)
          {
            // Attempt to register the user
            try
             {
               WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
               WebSecurity.Login(model.UserName, model.Password);
               ViewBag.Message = "Successfully Registered!";
               return View(model);//PRG has not been Maintained
             }
              catch (MembershipCreateUserException e)
             {
                 ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
             }
          }
            // If we got this far, something failed, redisplay form
            return View(model);
        }


    Image 3 : New user has been Created

New user has been Created

        
  • At this point If you try to Refresh (F5) or Reload the Page,You'll see below mentioned kind of Security Alert Message Box

      Image 4 : Register form with "Confirm Form Resubmission" Message Box

        Register form with "Confirm Form Resubmission" Message Box


  • After that If you try to press "Continue" Button, You'll see below mentioned Run time exception
  • But for another situation this may be Data Duplication issue etc.

      Image 5 : Run time Exception

Run time Exception


How to Get Rid Of this Issue ?

  • You have to maintain PRG Pattern with your Return type, After finishing the Successful Registration
  • To properly perform PRG you must return a redirecting ViewResult from your Action
  • Such as RedirectToAction, otherwise you'll get the dialog box pictured above (i.e. Image 4)

Code for the Properly Perform PRG Pattern is Maintaining Register Action Method is as below

    /// <summary>
    /// for Registering the User
    /// </summary>
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Register(RegisterModel model)
     {
      if (ModelState.IsValid)
      {
       // Attempt to register the user
       try
       {
         WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
         WebSecurity.Login(model.UserName, model.Password);
         
         return RedirectToAction("Index""Home");//PRG has been Maintained
        }
        catch (MembershipCreateUserException e)
        {
          ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
        }
      }
       // If we got this far, something failed, redisplay form
       return View(model);
     }


       Image 6 : Home page

Home page


That's It.You're Done.

Download











Conclusion

  • You saw that, by implementing the PRG pattern, You could have nice clean urls that are bookmarkable
  • Users of your web application also get a nice site that is traversable and aren't presented with confusing security dialog messages
  • So as a Best Practice, You must always try to use PRG pattern with your Post Action methods

I hope this helps to You.Comments and feedback greatly appreciated.

If you feel it was a good article,Give me a +1.Thank You.
 



You Might Also Like

26 comments:

  1. Replies
    1. Hi,

      Thanks for commenting.
      keep visiting.

      Delete
  2. Replies
    1. Hi Claudio,

      You're warmly welcome.
      Keep in Touch.

      Delete
  3. Replies
    1. Hi Blog,

      Thanks for your feedback.
      Keep in Touch.

      Delete
  4. Replies
    1. Hi varun,

      Thanks, I’m glad you enjoyed it!

      Delete
  5. Replies
    1. Hi Lakmal,

      You're welcome.
      Keep in Touch.

      Delete
  6. You didn't explain why we have to go for this PRG pattern. What is the benefit?

    ReplyDelete
    Replies
    1. Hi Vijay,

      Thanks for your feedback.

      About your Question:
      This whole article is about why we have to use PRG Pattern.
      Any way in short I can say it likes this : If you want to avoid "Confirm Form Resubmission" kind of annoying popups (Image 4) are generating when you Refresh the page or reload the page, after posting the data you have to use PRG.
      As I mentioned on my article, this kind of popups will lead towards the run time exceptions or data duplication issues according to your application.So for avoid such a scenarios you must use PRG Pattern with your MVC App.
      I hope you got my point.If you need to clarify more Plz let me know.

      Delete
  7. Nice article. Thank You, Sampath

    -Saif Kassim-

    ReplyDelete
    Replies
    1. Hi Saif,

      You're warmly welcome.
      Keep in Touch.

      Delete
  8. thanks 4 ur handy tricks/solution

    -Vinay Arora-

    ReplyDelete
    Replies
    1. Hi Vinay,

      Glad to hear that it helped!
      Keep in Touch.

      Delete
  9. Replies
    1. Hi Dasun,

      Thanks, I’m glad you enjoyed it!

      Delete
  10. Really amazing! I like this post and information which you share with us.ASP.NET developers

    ReplyDelete
    Replies
    1. Hi Andrew,

      Thanks, I’m glad you found it useful!
      Keep in Touch.

      Delete
  11. Nice article. Keep up the good work.!

    ReplyDelete
    Replies
    1. Hi Safeer,

      Thanks, I’m glad you enjoyed it!
      Keep in Touch.

      Delete
  12. Hi, Nice description about how to Use PRG Pattern with ASP.net MVC.Thanks, its really helped me a lot

    -Aparna
    Theosoft

    ReplyDelete
    Replies
    1. Hi Aparna,

      Thanks.Glad to hear that it helped.
      Keep in Touch.

      Delete
  13. Sampath,
    In your final example, just before your redirection to /home/index, you assign a value of "Successfully Registered!" to ViewBag.Message but this is redundant because the view will not register it.

    ReplyDelete
    Replies
    1. Hi MikeB,

      Yes.You're right.I have corrected it.Thanks for your feedback. :)

      Delete

Thanks for your Feedback.