First, configure ASP.NET Core 2 Startup
to re-execute to an error page for any errors from the web server and any unhandled exceptions.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment()) {
// Debug config here...
} else {
app.UseStatusCodePagesWithReExecute("/Error");
app.UseExceptionHandler("/Error");
}
// More config...
}
Next, define an exception type that will let you throw errors with HTTP status codes.
public class HttpException : Exception
{
public HttpException(HttpStatusCode statusCode) { StatusCode = statusCode; }
public HttpStatusCode StatusCode { get; private set; }
}
Finally, in your controller for the error page, customize the response based on the reason for the error and whether the response will be seen directly by an end user. This code assumes all API URLs start with /api/
.
[AllowAnonymous]
public IActionResult Error()
{
// Gets the status code from the exception or web server.
var statusCode = HttpContext.Features.Get<IExceptionHandlerFeature>()?.Error is HttpException httpEx ?
httpEx.StatusCode : (HttpStatusCode)Response.StatusCode;
// For API errors, responds with just the status code (no page).
if (HttpContext.Features.Get<IHttpRequestFeature>().RawTarget.StartsWith("/api/", StringComparison.Ordinal))
return StatusCode((int)statusCode);
// Creates a view model for a user-friendly error page.
string text = null;
switch (statusCode) {
case HttpStatusCode.NotFound: text = "Page not found."; break;
// Add more as desired.
}
return View("Error", new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier, ErrorText = text });
}
ASP.NET Core will log the error detail for you to debug with, so a status code may be all you want to provide to a (potentially untrusted) requester. If you want to show more info, you can enhance HttpException
to provide it. For API errors, you can put JSON-encoded error info in the message body by replacing return StatusCode...
with return Json...
.