Thursday, February 14, 2013

ASP.NET Web API with HealthMonitoring

After deploying a ASP.NET Web API app it was realized that exceptions were not being reported via the built in Health Monitoring features provided by ASP.NET.  The following shows how to get the healthMonitoring element to report on exceptions thrown inside a Web API controller.  It was inspired by Andrew Wilinski's post about getting ASP.NET MVC's HandleErrorAttribute to invoke the built in health monitoring features.

Of note, it appears that the HandleErrorAttribute in MVC 4.0 now invokes the health monitoring features and Andrew's fix is not required for the MVC controllers you're used to using.  ASP.NET Web API on the other hand uses a different set of exception filters then ASP.NET MVC and thus we need a slight variant of Andrew's fix to get health monitoring working with it.  Similar to how this feature wasn't implemented by Microsoft at first, I'm sure that one of the subsequent versions of the Web API code will hook into the health monitoring.

The following should allow exceptions thrown in a ASP.NET Web API controller to be reported by Health Monitoring.

Create the following two classes in a file called HealthMonitor.cs:

    public class WebRequestErrorEventWebApi : WebRequestErrorEvent
        public WebRequestErrorEventWebApi(string message, object eventSource, int eventCode, Exception exception) : base(message, eventSource, eventCode, exception) { }

        public WebRequestErrorEventWebApi(string message, object eventSource, int eventCode, int eventDetailCode, Exception exception) : base(message, eventSource, eventCode, eventDetailCode, exception) { }

    public class ExceptionFilterWebApiAttribute : ExceptionFilterAttribute
        public override void OnException(HttpActionExecutedContext actionExecutedContext)

            new WebRequestErrorEventWebApi("An unhandled exception has occurred.", this, 103005, actionExecutedContext.Exception).Raise();

You'll need the following using statements:

using System.Web.Http.Filters;
using System.Web.Management;

Then make sure the following is called from within Application_Start in global.asax.cs or refactor the code into WebApiConfig.Register (the WebApiConfig class is created in the App_Start directory by the web api website template)

GlobalConfiguration.Configuration.Filters.Add(new ExceptionFilterWebApiAttribute());

As long as you've configured your health monitoring properly, you should be all set.