Easier error handling in ASP.NET MVC5
I’ve written a few posts about error handling in ASP.NET MVC. It’s not easy to get it right since the MVC pipeline uses a different error handling method than ASP.NET itself. With our client library you can get a fully working implementation for free, without having to using the rest of our service.
OneTrueError injects itself both in the ASP.NET pipeline and by using an integration point in MVC5. To activate OneTrueError you have to download our “onetrueerror.mvc5″ package. You can activate it by using OneTrue.Configuration.CatchMvcExceptions()
. That means that all exceptions will be handled by our library without reporting them to our service. To catch and log all exceptions you can use OneTrue.Configuration.AddSubmitter(new YourLogAdapter())
.
Reporting error to our service
To get all of our features you have to create an account at OneTrueError and invoke OneTrue.Configuration.Credentials(appKey, sharedSecret);
When you visit our dashboard you’ll see that we are identifying tags for ASP.NET and MVC. Click on any of the tags to search StackOverflow for the error message (filtering on the tag that you clicked on).
MVC specific information
We capture MVC specific information each time we process a new exception. You get for instance information about the controller that is executing, the route that was chosen, the result that have been specified (if any).
RouteData
Do you wonder which route was used when the user got the error?
ViewBag
Are you using the ViewBag
instead of a view model?
ViewBag.User = new
{
FirstName = "Arne",
LastName = "Colt",
Age = 37,
Address = new {ZipCode = 12345}
};
No worries (it’s MVC that stores it in the ViewData).
As you can see, OneTrueError also supports nested view models (and anonymous objects).
TempData
TempData is captured too.
TempData["Transaction"] = new
{
Amount = 20000,
Expires = DateTime.UtcNow.AddMinutes(5)
};
.. and more
We also collect the following HTTP/MVC specific information (if available):
- Controller class name
- ActionResult information
- Child Action Context
- HTTP Request/Form/Files/Session/QueryString
- Information stored in HttpApplication
Error pages
When it comes to error pages we support several options.
The first option is to simply create an Error.cshtml
in your Views\Shared
folder.
Here is a sample file:
@model OneTrueError.AspNet.Mvc5.OneTrueViewModel
<div>
<h1>@Model.HttpStatusCodeName</h1>
<p>Failed to execute!</p>
</div>
<div>
<p>@Model.Exception</p>
</div>
The ViewModel that is passed have the following information:
/// <summary>
/// View model for all error pages used by this plugin.
/// </summary>
public class OneTrueViewModel
{
/// <summary>
/// Caught exception
/// </summary>
public Exception Exception { get; set; }
/// <summary>
/// Http status code. Typically 404 or 500
/// </summary>
public int HttpStatusCode { get; set; }
/// <summary>
/// Name of HTTP Status Code, like "InternalServerError"
/// </summary>
public string HttpStatusCodeName { get; set; }
/// <summary>
/// OneTrueError error id
/// </summary>
public string ErrorId { get; set; }
}
View per error
You can also create a Views\Errors
folder in which you place files named as the http status code.
They are automatically detected and used by the library.
Error controller
If you want to customize the error pages even further you can create your own ErrorController
and place it in the Controller
folder. It works just like any other controller. The only difference is that our library detect it and invoke it upon an error.
public class ErrorController : Controller
{
public ActionResult Index()
{
var model = RouteData.DataTokens["OneTrueModel"];
return View("Error", model);
}
}
You can of course use your own view model if you want to.
We also support action methods for different HTTP errors:
public class ErrorController : Controller
{
public ActionResult Index()
{
var model = RouteData.DataTokens["OneTrueModel"];
return View("Error", model);
}
public ActionResult NotFound()
{
var model = RouteData.DataTokens["OneTrueModel"];
return View(model);
}
public ActionResult InternalServerError()
{
var model = RouteData.DataTokens["OneTrueModel"];
return View(model);
}
}
Error pages
We have a set of default pages that are used unless you create your own. These will always be returned with the appropriate http status code.
Do note that if the accept type is JSON or XML we’ll return the error pages in those formats instead.
Not found
The requested URL (or internal resource) could not be found.
Currently, this page will be used if the exception is:
- HttpException with status code 404
- ObjectNotFoundException (Entity Framework)
Unauthorized
Unauthorized means that the must login to be able to access the requested page.
This page will be used if the exception is:
- HttpException with status code 401
- UnauthorizedAccessException
Forbidden
Forbidden means that the user have logged in, but do not have enough privileges to access the requested page.
This page will be used if the exception is:
- HttpException with status code 403
- SecurityException
Fallback page
If none of the above conditions apply we’ll display the following error page.
Dashboard
You will of course get all the usual features of OneTrueError like the dashboard
Reference: | Easier error handling in ASP.NET MVC5 from our NCG partner Jonas Gauffin at the jgauffin’s coding den blog. |