.NET  

Post-Redirect-Get (PRG) Pattern Example in ASP.NET Core

Web applications often involve form submissions where users post data to the server. A common issue arises when a user refreshes the page after submitting a form: the browser resends the POST request, potentially causing duplicate submissions. To mitigate this, developers employ the Post-Redirect-Get (PRG) pattern, a widely recognized design approach that enhances user experience and prevents unintended duplicate actions.

Understanding the PRG Pattern

The PRG pattern follows a simple workflow:

  1. Post: The client submits data via an HTTP POST request.

  2. Redirect: The server processes the request and issues an HTTP redirect (usually 302 Found) to a new URL.

  3. Get: The client follows the redirect and issues an HTTP GET request to retrieve the updated resource or confirmation page.

This ensures that refreshing the page only repeats the GET request, not the original POST, thereby avoiding duplicate submissions.

Benefits of PRG

  • Prevents Duplicate Form Submissions: Refreshing or navigating back does not resubmit the POST request.

  • Improves User Experience: Users see a clean confirmation or result page after submission.

  • Supports Bookmarking and Sharing: Since the final step is a GET request, the resulting URL can be bookmarked or shared.

  • Aligns with REST Principles: GET requests are idempotent, making them safe for repeated execution.

When to Use the PRG Pattern

  • Form Submissions: Use PRG for any scenario where a form submission can create or change server-side data (e.g., orders, registrations, comments).

  • Multi-Step Processes: It’s useful in multi-step forms or wizards where each step might commit data changes that should not be duplicated.

Example Implementation in ASP.NET Core

Step 1: Create the Model

public class Feedback
{
    public string Name { get; set; }
    public string Comments { get; set; }
}

Step 2: Create the Controller

public class FeedbackController : Controller
{
    [HttpGet]
    public IActionResult Submit()
    {
        return View();
    }

    [HttpPost]
    public IActionResult Submit(Feedback model)
    {
        if (ModelState.IsValid)
        {
            // Process the feedback (e.g., save to database)
            
            // Redirect to confirmation page using PRG
            return RedirectToAction("Confirmation");
        }
        return View(model);
    }

    [HttpGet]
    public IActionResult Confirmation()
    {
        return View();
    }
}

Step 3: Create the Views

  • Submit.cshtml: Contains the feedback form.

  • Confirmation.cshtml: Displays a success message after submission.

Workflow Explanation

  1. The user navigates to /Feedback/Submit and fills out the form.

  2. On submission, the form data is posted to the server via POST.

  3. The server processes the data and issues a redirect to /Feedback/Confirmation.

  4. The browser follows the redirect and performs a GET request to display the confirmation page.

  5. If the user refreshes the confirmation page, only the GET request is repeated, not the original POST.

Best Practices

  • Always validate input before redirecting.

  • Use TempData to pass short-lived messages (e.g., success notifications) across redirects.

  • Ensure redirects point to meaningful pages that provide feedback to the user.

  • Combine PRG with anti-forgery tokens for secure form submissions.

The Post-Redirect-Get (PRG) pattern is a robust solution to the problem of duplicate form submissions in web applications. ASP.NET Core provides straightforward mechanisms to implement PRG using RedirectToAction or Redirect. By adopting this pattern, developers can create applications that are more user-friendly, secure, and aligned with web standards.