Welcome to today’s post.
I will be showing you how to trap and handle exceptions in your .NET Core applications.
In the Configure() methodwithinthe Startup.cs source, you can conditionally setup exception handling using the IsDevelopment() method in the IHostingEnvironment class test as shown below:
public void Configure(IApplicationBuilder app,
IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
…
}
As a precaution, you should only enable the developer exception page when the application is running in the development environment. In production the developer exception page should NEVER be used.
In addition, you will need an error page to display the error in your /View/Shared folder.
A simple error page (non-razor) is show below:
@model ErrorViewModel
@{
ViewData["Title"] = "Error";
}
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
</p>
Another more extensible way of implementing an error handler is by creating a controller and scaffolded Razor page for the Error response. Then call the Error page from the controller with a user error message.
This is done as follows:
Error page view:
@model BookLoan.Views.Common.ErrorModel;
@*@{
ViewData["Title"] = "Error";
}*@
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
@if (Model.ShowReferrer)
{
<h3>Referrer</h3>
<p>
<a href="@Model.Referrer">@Model.Referrer</a>
</p>
}
@if (@Model.ShowExceptionMessage)
{
<h3>Exception Message</h3>
<p>
@Model.ExceptionMessage
</p>
}
Error page code-behind (generated as part of the scaffold):
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace BookLoan.Views.Common
{
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class ErrorModel : PageModel
{
public string RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
public string Referrer { get; set; }
public bool ShowReferrer => !string.IsNullOrEmpty(Referrer);
public string ExceptionMessage { get; set; }
public bool ShowExceptionMessage => !string.IsNullOrEmpty(ExceptionMessage);
public void OnGet()
{
}
}
}
The controller is just:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using BookLoan.Models;
using Microsoft.AspNetCore.Authorization;
using BookLoan.Views.Common;
namespace BookLoan.Controllers
{
public class CommonController: Controller
{
[HttpGet]
public IActionResult Error(string errorMessage)
{
BookLoan.Views.Common.ErrorModel errorModel = new BookLoan.Views.Common.ErrorModel()
{
ExceptionMessage = errorMessage,
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier
};
ViewData["Title"] = "Error";
return View(errorModel);
}
}
}
Model definition for the Error view is:
using System;
namespace BookLoan.Models
{
public class ErrorViewModel
{
public string RequestId { get; set; }
public string ExceptionMessage { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
}
When run, the above should have you an error page like this:

To prevent verbose error messages for the custom error handler, check the environment as follows:
[HttpGet]
public async Task<ActionResult> Search(string BookGenre,
string SearchString)
{
try
{
// Do some processing
}
catch (Exception ex)
{
if (Environment.GetEnvironmentVariable ("ASPNETCORE_ENVIRONMENT") == "Development")
{
return RedirectToAction("Error", "Common", new { errorMessage = ex.Message.ToString() } );
}
return RedirectToAction("Error", "Common",
new { errorMessage =
"Error running searching. Please contact support."
});
}
}
To handle database exception pages to your middleware, use the UseDatabaseErrorPage() method of IApplicationBuilder.
To use the Status Code Pages middleware to display a default error response use the UseStatusCodePages() of IApplicationBuilder.
An example of a default error response is the 404 error:
Status Code: 404; Not Found
To redirect the error to a custom status code error page, use the UseStatusCodePagesWithRedirects() method of IApplicationBuilder with a query string as shown:
app.UseStatusCodePagesWithRedirects("/StatusCode?code={0}");
Below is the Razor page csHTML:
@model BookLoan.Models.StatusCodeViewModel
@{
ViewData["Title"] = "Status Code";
}
<h1 class="text-danger">Status Code: @Model.ErrorStatusCode</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<h3>Request ID</h3>
<p>
<code>@Model.RequestId</code>
</p>
}
@if (Model.ShowOriginalURL)
{
<h3>Original URL</h3>
<p>
<code>@Model.OriginalURL</code>
</p>
}
Below is the Razor code behind:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
namespace BookLoan.Views.Common
{
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class StatusCodeModel : PageModel
{
private readonly ILogger _logger;
public string RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
public string ErrorStatusCode { get; set; }
public string OriginalURL { get; set; }
public bool ShowOriginalURL => !string.IsNullOrEmpty(OriginalURL);
public StatusCodeModel(ILogger<StatusCodeModel> logger)
{
_logger = logger;
}
public void OnGet(string code)
{
}
}
}
Controller code:
[HttpGet]
public IActionResult StatusCode(int? code = null)
{
string referer = Request.Headers["Referer"].ToString();
BookLoan.Models.StatusCodeViewModel statuscodeModel = new BookLoan.Models.StatusCodeViewModel()
{
OriginalURL = referer,
ErrorStatusCode = "",
ExceptionMessage = "An error has occurred",
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier
};
if (code.HasValue)
{
statuscodeModel.ErrorStatusCode = code.ToString();
ViewData["Title"] = "Error " + code.ToString();
return View(statuscodeModel);
}
statuscodeModel.ExceptionMessage = "";
return View(statuscodeModel);
}
Model definition for the status code:
using System;
namespace BookLoan.Models
{
public class StatusCodeViewModel : ErrorViewModel
{
public string OriginalURL { get; set; }
public bool ShowOriginalURL { get; set; }
public string ErrorStatusCode { get; set; }
}
}
When run, navigate to a non-existent URL. The following page is what you will see:

To summarize, you have seen how to trap exceptions globally and locally in your .NET Core applications.
I hope this post has been informative and useful for your applications.

Andrew Halil is a blogger, author and software developer with expertise of many areas in the information technology industry including full-stack web and native cloud based development, test driven development and Devops.