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

  • Diving Deep into .NET MAUI

    Ever since someone figured out that fiddling bits results in source code, developers have sought one codebase for all types of apps on all platforms, with Microsoft's latest attempt to further that effort being .NET MAUI.

  • Copilot AI Boosts Abound in New VS Code v1.96

    Microsoft improved on its new "Copilot Edit" functionality in the latest release of Visual Studio Code, v1.96, its open-source based code editor that has become the most popular in the world according to many surveys.

  • AdaBoost Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the AdaBoost.R2 algorithm for regression problems (where the goal is to predict a single numeric value). The implementation follows the original source research paper closely, so you can use it as a guide for customization for specific scenarios.

  • Versioning and Documenting ASP.NET Core Services

    Building an API with ASP.NET Core is only half the job. If your API is going to live more than one release cycle, you're going to need to version it. If you have other people building clients for it, you're going to need to document it.

  • TypeScript Tops New JetBrains 'Language Promise Index'

    In its latest annual developer ecosystem report, JetBrains introduced a new "Language Promise Index" topped by Microsoft's TypeScript programming language.

Subscribe on YouTube