Thoughts from the Wet Coast

The musings of an ASP.NET Developer from Canada's We(s)t Coast

DNN Development Tips:4 - Using the DnnExceptionFilterAttribute in your Service Framework Methods

Last Modified: May 2 2017
Oct 16 2014

Often when writing DNN Service Framework methods (based on ASP.NET Web API) you find yourself writing the same boiler plate error-handling code.  Figure 1 shows an example of this boiler-plate code.

Figure 1: An example of a Service Framework Action Method

   1:  [HttpPost]
   2:  public HttpResponseMessage DeleteTask(TaskDTO taskDTO)
   3:  {
   4:    try
   5:    {
   6:      using (var context = DataContext.Instance())
   7:      {
   8:        var repo = context.GetRepository();
   9:        var task = repo.GetById(taskDTO.TaskId, ActiveModule.ModuleID);
  11:        repo.Delete(task);
  12:        var result = new {Result = "success"};
  13:        return Request.CreateResponse(HttpStatusCode.OK, result);
  14:      }
  15:    }
  16:    catch (Exception exc)
  17:    {
  18:      var result = new { Result = exc.Message };
  19:      return Request.CreateResponse(HttpStatusCode.InternalServerError, result);
  20:    }
  21:  }

This is great that we write code with explicit error handling, but it can get repetitive.  Fortunately ASP.NET Web API provides a way to make this a lot easier – to encourage us to use good error-handling practices.  Web API provides an ExceptionFilterAttribute base class.  This attribute can be applied at the class level or at the method level.  If applied at the class level it applies to all action methods. in the class.   The ExceptionFilterAttribute base class has one method OnException which is called if there is an unhandled exception in the action method.

In order to provide support for DNN’s localization framework, the Dnn Services Framework includes a subclass of this base class – DnnExceptionFilterAttribute.  This class provides two properties which gives the developer the ability to provide a MessageKey, and a LocalResourceFile.  Each of these has a default – MessageKey defaults to {ControllerName}_{ActionName}.Error where ControllerName is the name of the controller class and ActionName is the name of the action method where the error occurs, and LocalResourceFile defaults to the global Exceptions.resx resource file.

Lets see how our Delete action method will look if we use the DnnExceptionFilterAttribute.

Figure 2: The Delete Action Method modified to use DnnExceptionFilter

   1:  [HttpPost]
   2:  [DnnExceptionFilter(MessageKey = "DeleteTask.Error")]
   3:  public HttpResponseMessage DeleteTask(TaskDTO taskDTO)
   4:  {
   5:    using (var context = DataContext.Instance())
   6:    {
   7:      var repo = context.GetRepository();
   8:      var task = repo.GetById(taskDTO.TaskId, ActiveModule.ModuleID);
  10:      repo.Delete(task);
  11:      var result = new {Result = "success"};
  12:      return Request.CreateResponse(HttpStatusCode.OK, result);
  13:    }
  14:  }

This is a lot less work to do – while still retaining excellent error-handling.


The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.