Support us .Net Basics C# SQL ASP.NET Aarvi MVC Slides C# Programs Subscribe Download

UseStatusCodePagesWithRedirects vs UseStatusCodePagesWithReExecute

Suggested Videos
Part 56 - httppost edit action in asp.net core mvc | Text | Slides
Part 57 - Handling 404 not found in asp.net core mvc | Text | Slides
Part 58 - Centralised 404 error handling in ASP.NET Core | Text | Slides

In this video we will discuss the difference between UseStatusCodePagesWithRedirects and UseStatusCodePagesWithReExecute middleware. This is continuation to Part 58. I strongly recommend to watch Part 58 from ASP.NET core tutorial before proceeding with this video.


Irrespective of the middleware component you use, from an end user standpoint, there is no difference in the behaviour. We see the specified custom error view in both the cases.


UseStatusCodePagesWithRedirects
  • app.UseStatusCodePagesWithRedirects("/Error/{0}");
  • When a request is issued to http://localhost/foo/bar
  • Since this URL does not match with any route in our application status code 404 is raised
  • UseStatusCodePagesWithRedirects middleware component intercepts the 404 status code and as the name implies, issues a redirect to the provided error path (in our case "/Error/404")
Request processing with UseStatusCodePagesWithRedirects
  • When a request is issued to http://localhost/foo/bar
  • 404 status code is raised 
  • StatusCodePagesWithRedirects middleware intercepts this and changes it to 302, pointing it to the error path (/Error/404)
  • 302 status code means the URI of the requested resource has been changed temporarily, in our case it changed to /Error/404
  • So another GET request is issued to serve the redirected request
  • Because a redirect is issued, notice the URL in the address bar also changes from /foo/bar to /Error/404
  • The request flows through the pipeline and handled by the MVC middleware which ultimately returns NotFound view HTML with status code 200(which means the request completed successfully)
  • As far as the browser is concerned in this entire request flow there was no 404 error.
  • If you closely observe this request and response flow, we are returning a success status code (200) when actually an error occurred which isn't semantically correct.
UseStatusCodePagesWithRedirects vs UseStatusCodePagesWithReExecute

Request processing with UseStatusCodePagesWithReExecute
  • app.UseStatusCodePagesWithReExecute("/Error/{0}")
  • When a request is issued to http://localhost/foo/bar
  • 404 status code is raised 
  • UseStatusCodePagesWithReExecute middleware intercepts the 404 status code and re-executes the pipeline pointing it to the URL  (/Error/404)
  • The request flows through the pipeline and handled by the MVC middleware which returns NotFound view HTML along with status code 200
  • As the response flows out to the client, it passes through UseStatusCodePagesWithReExecute middleware which uses the HTML response but replaces the 200 status code with the original 404 status code.
  • This is a clever piece of middleware. As the name implies it re-executes the pipeline keeping the correct (404) status code. It just returns the custom view (NotFound) HTML
  • As it is just re-executing the pipeline and not issuing a redirect request, we also preserve the original URL (/foo/bar) in the address bar. It does not change from /foo/bar to /Error/404.
usestatuscodepageswithreexecute vs usestatuscodepageswithredirects

If you are using UseStatusCodePagesWithReExecute middleware, it's also possible to get the original path in the ErrorController using IStatusCodeReExecuteFeature interface as shown below.

public class ErrorController : Controller
{
    [Route("Error/{statusCode}")]
    public IActionResult HttpStatusCodeHandler(int statusCode)
    {
        var statusCodeResult =
                HttpContext.Features.Get<IStatusCodeReExecuteFeature>();

        switch (statusCode)
        {
            case 404:
                ViewBag.ErrorMessage =
                        "Sorry, the resource you requested could not be found";
                ViewBag.Path = statusCodeResult.OriginalPath;
                ViewBag.QS = statusCodeResult.OriginalQueryString;
                break;
        }

        return View("NotFound");
    }
}

You can then display it in the custom error view as shown below

@{
    ViewBag.Title = "Not Found";
}

<h1>@ViewBag.ErrorMessage</h1>

<h1>@ViewBag.Path</h1>

<h1>@ViewBag.QS</h1>

<a asp-action="index" asp-controller="home">
    Click here to navigate to the home page
</a>

asp.net core tutorial for beginners

2 comments:

  1. In my Error controller the HttpContext.Features.Get(); always returns null.

    ReplyDelete
  2. use app.UseStatusCodePagesWithReExecute("/Error/{0}"); in Startup.Configure() method at place of app.UseStatusCodePagesWithRedirects("/Error/{0}");
    it will work.

    Ashutosh Kumar Dubey

    ReplyDelete

It would be great if you can help share these free resources