Display Errors with ASP.NET Core:

Display Errors with ASP.NET Core
Display Errors with ASP.NET Core

When developing applications with ASP.NET Core, handling and displaying errors effectively is crucial for both debugging during development and providing a seamless user experience in production. In this comprehensive guide, we will explore various methods to manage and display errors in ASP.NET Core applications. From simple error pages to advanced exception handling, we will cover everything you need to ensure your application is robust and user-friendly.

Understanding Error Handling in ASP.NET Core

Error Handling Middleware

ASP.NET Core uses middleware to manage the request pipeline. One of the key pieces of middleware for error handling is the DeveloperExceptionPageMiddleware, which provides detailed error information during development.

To enable this middleware, add the following code to the Startup.cs file:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

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

    app.UseAuthorization();

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

In development mode, the UseDeveloperExceptionPage middleware provides a rich error page that includes stack traces and request information.

Custom Error Pages

In a production environment, detailed error information should not be exposed to end-users. Instead, custom error pages can be used to provide a user-friendly message while logging the details for further investigation.

To set up custom error pages, configure the ExceptionHandler middleware in the Startup.cs file:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (!env.IsDevelopment())
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

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

    app.UseAuthorization();

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

Then, create an Error action in the HomeController and a corresponding Error.cshtml view:

HomeController.cs:

public class HomeController : Controller
{
    public IActionResult Error()
    {
        return View();
    }
}

Error.cshtml:

@{
    ViewData["Title"] = "Error";
}

<h1>Error</h1>
<p>Sorry, an unexpected error occurred. Please try again later.</p>

Status Code Pages Middleware

The StatusCodePages middleware allows you to provide user-friendly messages for different HTTP status codes, such as 404 Not Found or 500 Internal Server Error.

To configure status code pages, add the following to the Configure method in Startup.cs:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (!env.IsDevelopment())
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

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

    app.UseStatusCodePagesWithReExecute("/Home/StatusCode", "?code={0}");

    app.UseAuthorization();

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

Next, create an action in the HomeController to handle status codes:

HomeController.cs:

public IActionResult StatusCode(int code)
{
    ViewData["ErrorCode"] = code;
    return View();
}

StatusCode.cshtml:

@{
    ViewData["Title"] = "Error";
    var errorCode = ViewData["ErrorCode"];
}

<h1>Error @errorCode</h1>
<p>Sorry, an error occurred. Error code: @errorCode</p>

Advanced Error Handling Techniques

Using Exception Filters

Exception Filters provide a way to handle exceptions globally or at the controller level in ASP.NET Core MVC. They allow for custom logic to be executed when an unhandled exception occurs.

To create a global exception filter, first create a custom filter class:

CustomExceptionFilter.cs:

public class CustomExceptionFilter : IExceptionFilter
{
    private readonly ILogger<CustomExceptionFilter> _logger;

    public CustomExceptionFilter(ILogger<CustomExceptionFilter> logger)
    {
        _logger = logger;
    }

    public void OnException(ExceptionContext context)
    {
        _logger.LogError(context.Exception, "An unhandled exception occurred.");
        context.Result = new RedirectToActionResult("Error", "Home", null);
    }
}

Then, register the filter in the Startup.cs file:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews(options =>
    {
        options.Filters.Add<CustomExceptionFilter>();
    });
}

Logging Errors

Effective logging is essential for diagnosing and troubleshooting errors in your application. ASP.NET Core integrates seamlessly with various logging frameworks.

To configure logging, add the following to the appsettings.json file:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

In the Startup.cs file, configure the logging services:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILogger<Startup> logger)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

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

    app.UseStatusCodePagesWithReExecute("/Home/StatusCode", "?code={0}");

    app.UseAuthorization();

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

    app.Use(async (context, next) =>
    {
        try
        {
            await next.Invoke();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "An unhandled exception has occurred.");
            throw;
        }
    });
}

Handling Errors in Web API

For ASP.NET Core Web API projects, handling errors requires a slightly different approach. Custom error responses can be provided using exception filters or middleware.

Here is an example of a custom exception filter for a Web API:

ApiExceptionFilter.cs:

public class ApiExceptionFilter : IExceptionFilter
{
    public void OnException(ExceptionContext context)
    {
        context.Result = new ObjectResult(new
        {
            Error = context.Exception.Message,
            StackTrace = context.Exception.StackTrace
        })
        {
            StatusCode = 500
        };
    }
}

Register the filter in the Startup.cs file:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers(options =>
    {
        options.Filters.Add<ApiExceptionFilter>();
    });
}

Conclusion

Proper error handling in ASP.NET Core applications is essential for both development and production environments. By implementing the techniques outlined in this guide, you can ensure your application gracefully handles errors, providing a better experience for users and easier debugging for developers.

If you want to read more information about how to boost traffic on your Website just visit –> The Insider’s Views.