Error Pages Based on Status Code in ASP.NET Core MVC

Error Pages Based on Status Code in ASP.NET Core MVC

In this article, I will discuss Error Pages Based on Status Codes in ASP.NET Core MVC Applications with Examples. Please read our previous article discussing Handling Non-Success HTTP Status Codes in ASP.NET Core MVC Application.

HTTP Status Codes:

HTTP Status Codes are used to indicate the outcome of an HTTP Request. Non-success HTTP status codes indicate errors or specific conditions that have occurred during the request-response cycle. In ASP.NET Core MVC, you can handle these non-success status codes to provide meaningful responses to the client. The following are some of the standard non-success HTTP status codes in ASP.NET Core MVC:

  • 400 Bad Request: This status code is used when the server cannot understand the request due to invalid syntax or client-side errors.
  • 401 Unauthorized: This status code indicates the request lacks valid authentication credentials.
  • 403 Forbidden: This status code is used when the server understands the request but refuses to fulfill it, often due to insufficient permissions.
  • 404 Not Found: This status code indicates that the requested resource could not be found on the server.
  • 500 Internal Server Error: This status code is a generic error message indicating that something has gone wrong on the server.
  • 503 Service Unavailable: This status code is used when the server is temporarily unavailable to handle the request due to being overloaded or undergoing maintenance.
Error Pages Based on Status Code in ASP.NET Core MVC

In ASP.NET Core MVC, we can create custom error pages based on Non-Success HTTP status codes to provide a more user-friendly message when errors occur. Let us proceed and see how to create and return Custom Error Pages based on Non-Success HTTP Status Codes like 401, 404, 500, etc., in an ASP.NET Core MVC application.

As we already discussed in our previous article, we can configure the Error Handling Middleware (UseStatusCodePagesWithReExecute or UseStatusCodePagesWithRedirects middleware in the Program.cs file) to handle the Non-Success HTTP status code and render the appropriate custom error page.

Create Custom Error Views:

First, create specific error views for specific status codes you want to handle. These views will be displayed to the user when the corresponding HTTP status code is returned.

For example, you can create views like PageNotFoundError.cshtml for handling “Not Found” errors (HTTP status code 404) and InternalServerError.cshtml for handling server errors (HTTP status code 500). You must place these views inside the Views/Shared directory. 

Views/Shared/PageNotFoundError.cshtml
Views/Shared/InternalServerError.cshtml
Views/Shared/UnauthorizedError.cshtml
Views/Shared/GenericError.cshtml

Configuring Error Handling Middleware in ASP.NET Core:

In the Program.cs file, we need to configure the Error Middleware to return Custom Rrror Mages based on HTTP Status Codes. To use the UseStatusCodePagesWithReExecute middleware, add the following code to the Configure method:

app.UseStatusCodePagesWithReExecute(“/Error/{0}”);

This configuration tells ASP.NET Core to re-execute the request with the “Error” Route and pass the status code as a parameter to the action method. To use the UseStatusCodePagesWithRedirects middleware, you can use the following code:

app.UseStatusCodePagesWithRedirects(“/Error/{0}”);

This configuration will redirect the user to the Error Route with the corresponding status code in the URL. Let us proceed and implement this example step by step:

Creating Error Controller:

Create a controller with the name ErrorController within the Controllers folders. Once you create the Error Controller, please copy and paste the following code. When an error status code is encountered, the Index action in the ErrorController is executed with the status code as a parameter, and based on the status code, a specific error view is returned.

using Microsoft.AspNetCore.Mvc;

namespace FiltersDemo.Controllers
{
    public class ErrorController : Controller
    {
        [Route("Error/{statusCode}")]
        public IActionResult Index(int statusCode)
        {
            Response.Clear();
            Response.StatusCode = statusCode;

            switch (statusCode)
            {
                case 401:
                    return View("UnauthorizedError");
                case 404:
                    return View("PageNotFoundError");
                case 500:
                    return View("InternalServerError");
                default:
                    return View("GenericError");
            }
        }
    }
}
Creating Error Views:

Next, add the following views to the Views/Shared folder.

PageNotFoundError.cshtml
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>PageNotFound Error</title>
</head>
<body>
    <hgroup>
        <h1 style="color:red">Page Not Found Error</h1>
        <h2 style ="color:red">The Page you are trying to access is no longer available. Kindly check and submit the URL again</h2>
    </hgroup>
</body>
</html>
UnauthorizedError.cshtml
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Unauthorized Error</title>
</head>
<body>
    <hgroup>
        <h1 style="color:red">Unauthorized Error</h1>
        <h2 style="color:red">You donot have the permission to access this page. Kindly contact with your admin.</h2>
    </hgroup>
</body>
</html>
InternalServerError.cshtml
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Internal Server Error</title>
</head>
<body>
    <hgroup>
        <h1 style="color:red">Internal Server Error</h1>
        <h2 style="color:red">Some Internal Server error Occurred while processing your request. Kindly try after some time.</h2>
    </hgroup>
</body>
</html>
GenericError.cshtml
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Generic Error</title>
</head>
<body>
    <hgroup>
        <h1 style="color:red">Generic Error</h1>
        <h2 style="color:red">An unknown error has occurred. We are working on it. Please try after some time</h2>
    </hgroup>
</body>
</html>
Configuring Middleware in Program.cs:
namespace FiltersDemo
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // Add services to the container.
           
            builder.Services.AddControllersWithViews();

            var app = builder.Build();

            if (app.Environment.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseStatusCodePagesWithReExecute("/Error/{0}");
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");

            app.Run();
        }
    }
}

The following line of code configures the Middleware:

app.UseStatusCodePagesWithReExecute(“/Error/{0}”);

Modify Home Controller:

Next, modify the Home Controller as follows. Here, you can see that we have created different action methods to demonstrate the different types of Non-Success HTTP Status Codes. SomeAction1 will throw a 400 Bad Request HTTP Status Code. SomeAction2 will throw a 401 Unauthorized HTTP Status Code. SomeAction3 will throw a 403 Forbidden HTTP Status Code. SomeAction4 will throw a 404 Not Found HTTP Status Code. SomeAction5 will throw a 500 Internal Server Error HTTP Status Code. SomeAction6 will throw a 503 Service Unavailable Error HTTP Status Code. 

using Microsoft.AspNetCore.Mvc;

namespace FiltersDemo.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        //400 Bad Request
        public IActionResult SomeAction1()
        {
            var someConditionIsNotMet = true;
            if (someConditionIsNotMet)
            {
                return new StatusCodeResult(400);
            }
            // Other logic
            return View();
        }

        //401 Unauthorized
        public IActionResult SomeAction2()
        {
            var IsAuthenticated = false;
            if (!IsAuthenticated)
            {
                return Unauthorized(); // This will return a 401 status code
            }
            // Other logic
            return View();
        }

        //403 Forbidden
        public IActionResult SomeAction3()
        {
            var UserHasPermissionToAccessResource = false;
            if (!UserHasPermissionToAccessResource)
            { 
               return new StatusCodeResult(403);
            }
            // Other logic
            return View();
        }

        //404 Not Found
        public IActionResult SomeAction4()
        {
            var requestedResourceNotFound = true;
            if (requestedResourceNotFound)
            {
                return NotFound();
            }
            // Other logic
            return View();
        }

        //500 Internal Server Error
        public IActionResult SomeAction5()
        {
            try
            {
                // Some code that might throw an exception
                // ...
                throw new Exception("Some Exception Occurred");
                return Ok(); // If successful
            }
            catch (Exception ex)
            {
                // Log the exception
                return new StatusCodeResult(500);
            }
        }

        //503 Service Unavailable
        public IActionResult SomeAction6()
        {
            var isServiceUnavailable = true;
            if (isServiceUnavailable)
            {
                return new StatusCodeResult(503);
            }
            // Other logic
            return View();
        }
    }
}

Now, run the application and access the Home Controller Action Methods. You should see the respective error pages based on the Status Code.

In the next article, I will discuss the Result Filter in ASP.NET Core MVC Application. In this article, I try to explain Error Pages Based on Status Codes in ASP.NET Core MVC Applications with Examples. I hope you enjoy this Error Pages Based on Status Codes in the ASP.NET Core MVC article.

Leave a Reply

Your email address will not be published. Required fields are marked *