Practical .NET

Leverage Global Filters and the HandleError Attribute in ASP.NET MVC Apps

Here's how to combine adding HandleError attributes to your ASP.NET MVC application both through Global Filters and adding them directly to your Action methods.

The GlobalFilters object is a great way to associate an attribute with every Action method in your ASP.NET MVC application. I use GlobalFilters to put the Authorize attribute on every method and then use the AllowAnonymous to implement exceptions (I even called it a best practice when I discussed it in an earlier tip. If you're using the HandleError attribute with GlobalFilters you'll need a slightly more sophisticated approach.

For example, I use GlobalFilters to put the HandleError attribute in its basic state on every Action method, like this (I think some ASP.NET project templates even take care of this for you):

GlobalFilters.Filters.Add(New HandleErrorAttribute())

But there are some methods where I want to be able to handle specific errors in a specific way. Fortunately, by stacking my HandleError attributes in a sensible way I can customize how specific errors are handled.

The good news here is that any HandleError attribute added through GlobalFilters is, effectively, added at the bottom of the HandleError stack. The result is that any HandleError attribute you add directly to an Action method or Controller will be processed before any filter added through GlobalFilters. Effectively, then, any HandleError attributes added through a GlobalFilters form becomes your "default" HandleErrors, processed only after any HandleError attributes added directly to the Action method are processed. You can override them, just by adding a HandleError attribute directly to an Action method.

You can also add multiple HandleError attributes through GlobalFilters, though that only makes sense if those additional HandleError attributes are configured to handle particular errors. That means that you have to configure the HandleError attribute as you add it to the GlobalFIlters collection. Furthermore, order matters: The first attributes added to the GlobalFilters collection go higher in the stack and, therefore, are processed before any attributes added later to the GlobalFilters collection.

Here's an example where I add two attributes:

GlobalFilters.Filters.Add(New HandleErrorAttribute With { 
             .ExceptionType = GetType(NullReferenceException), 
             .View="NullReferenceError"})
GlobalFilters.Filters.Add(New HandleErrorAttribute())

The HandleErrorAttribute added "at the top" is configured to handle null reference exceptions, while the HandleError attribute with no customizations (my default HandleError attribute) is added "at the bottom," to handle all exceptions not processed by an attribute "higher" in the stack.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

Subscribe on YouTube