Sunday, 22 November 2009

Using the HandleError attribute

You can conveniently handle exceptions in ASP.Net MVC using the [HandleError] attribute. However, there are a few things to bear in mind.

Update Web.config

You must add a customerrors section to Web.config. If you don’t do this nothing will happen.

<configuration>
    <system.web>
        <customErrors mode="On" />
    </system.web>
<configuration>

Beware of adding the attribute to the controller at class level

If you add the attribute to your controller class at the class level it can override any settings made on controller actions.

using System;
using System.Web.Mvc;
using Mail.Merge.Core.Domain;
using Mail.Merge.Core.Repository;
using Mail.Merge.Core.Repository.Specification;
using Mail.Merge.UI.MVC.Extensions;

namespace Mail.Merge.UI.MVC.Controllers
{
    [HandleError] // This will override any settings made on controller actions
    public class SalutationController : Controller
    {
        IRepository _repository;

        public SalutationController(IRepository repository)
        {
            _repository = repository;
        }

        // code snipped ...

        [AcceptVerbs(HttpVerbs.Post)]
        [HandleError(ExceptionType=typeof(SqlException),View="DeletionError")]
        public ActionResult Delete(int id, string button)
        {
            // code snipped ...
            return RedirectToAction("Index");
        }
    }
}

You can fix this behaviour though by modifying the [HandleError] attributes to use explicit ordering. For example in the code above set the attribute at the class level to be [HandleError(Order=0)]. Because the default order number is –1 this will force the controller action error handling filter to take precedence.