15 julho, 2015

How to Use PRG Pattern with ASP.net MVC

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 ofSecurity 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 SuccessfulRegistration
      • To properly perform PRG you must return a redirecting ViewResult from your Action
      • Such as RedirectToActionotherwise 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.