LA.NET [EN]

Feb 06

Yesterday, we’ve seen how we can handle authorization with the AuthorizeAttribute and how it integrates with the MVC pipeline and with the ASP.NET authentication infrastructure. Today we’re going to keep looking at existing filters and we’ll see how we can use the HandleErrorAttribute for handling exceptions that be raised during the handling of a MVC request.

The HandleErrorAttribute expands the FilterAttribute class and implements the IExceptionfilter interface. This is a really simple interface with only one method:

public interface IExceptionFilter {
       void OnException(ExceptionContext filterContext);
}

As you can guess, this the method that  will be called whenever you have a non-treated exception in an action method. The HandleErrorAttribute implements this method and performs several interesting steps:

  • the first thing it does is check if the current exception has already been handled (probably by some  other filter that has been invoked before) or if custom errors are disabled for the current ASP.NET app (by checking the value of the IsCustomErrorEnabled property of the current ASP.NET context). If any of these is true, then the current filter won’t do anything;
  • after that, it needs to check the “type” of the current exception. If it’s a valid HTTP exception, it won’t do anything (in practice, if the current exception is not convertible to an HttpException with code 500 code, then the filter will simply return);
  • Besides checking the code, it will also see if you have set up the ExceptionType property. You can pass any derived Exception type to this property. Doing that means that the current exception filter will only run for exceptions derived from that type (this  lets you handle only some exceptions or have different views for different exception types);
  • only after doing all those checks will the filter do its “real” work: create a valid ViewResult from its ViewName and MasterName properties and pass that information to the Result property of the ExceptionContext that is passed into the OnException method. It will also change the value of the ExceptionHandled property (which is set to true) and change the status code of the response to 500.

To complete the analysis we still need to answer one question: when are these filters used? If you’ve read this series, then you know that they can only be used from within the ControllerActionInvoker class. What happens is that the InvokeAction method wraps the call to the current action method (which also involves executing authorization filters, action filters and result filters) in a try/catch block. Whenever an exception is triggered (and that exception is not a ThreadAbortException, which should only be triggered by a Response.Redirect call on a web app),it will be caught by that catch block and all the exceptions filters will be give an chance to run.

Even though this post has looked at exception filters,it’s also important to mention  that you don’t need to use this attribute to handle an exception. If  you want, you can also override the OnException method that you inherit from the abstract Controller class. As you’ve seen in the past, the ControllerInvokerAction class will also invoke those methods.

Before ending, there’s still time for an example of how you can use the HandleErrorAttribute. Here’s a snippet that shows how you can redirect the processing of the request to the PrintErrorView of the current controller when you  have and exception of type MyCustomException:

[
    HandleError(
            ExceptionType = typeof(MyCustomException),
            View = "PrintErrorView ")
]
public class HomeController : Controller {
//more code

Notice that you can also specify a master view page by setting the Master property of the HandleErrorAttribute class.

And that’s all for today. Keep tuned for more on the MVC framework.

1 comment so far

  1. Tri
    5:36 am - 2-10-2009

    I really like your posts. Thanks for sharing your knowledge

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>