Friday 19 July 2013

HandleErrorAttribute or Error handling in MVC3 Razor


  • Exception handling and Error handling is important in any application. 
  • We usually use try-catch loops at local level or applicatio events at global level to implement error handling. ASP.NET MVC provides built-in support for exception handling through exception filters.
  • The HandleError is the default built-in exception filter.
  • In this article we will see how to use HandleError attribute to hanlde exceptions.

What is Exception Filters ?

The exception filters are the attributes that can be applied at Action or controller or at the global level. When the filter is used at global level then it will handle the exceptions raised by all the actions of all controllers.

Every Exception filter implements the IExceptionFilter interface as shown below :
namespace System.Web.Mvc
{
    // Summary:
    //     Defines the methods that are required for an exception filter.
    public interface IExceptionFilter
    {
        // Summary:
        //     Called when an exception occurs.
        //
        // Parameters:
        //   filterContext:
        //     The filter context.
        void OnException(ExceptionContext filterContext);
    }
}

The interface has one method i.e. OnException which is called whenever an exception occurs. The ExceptionContext parameter which derives from ControllerContext provide access to the controller, route data and HttpContext. This is about the Interface.

Following are the steps :


Step 1 : Global.ascx

public class MvcApplication : System.Web.HttpApplication
    {
         //Like this
         //Section Highlighted
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }
        //Section Highlighted

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );

        }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
        }
    }

As HandleErrorAttribute is the default implementation of the IExceptionFilter, when we create a MVC3 Razor application you can find HandleErrorAttribute is added to the GlobalFiltersCollection in the Global.ascx.cs as shown above.

Step 2 : Action

In this steps we will see how use this attribute at action method level.
[HandleError(ExceptionType= typeof(NullReferenceException), View="ErrorView")]
        public ActionResult About(int id)
        {
            if (id == 5)
                throw new NullReferenceException("Something is wrong !!");
            return View();
        }

In the attribute definition we have specified the exception type and also specified the View. This statment ensures that whenever a NullReference exception will occur, it will render a view specified for View property. In order to test, we have raised the exception when id = 5 is passed.

Step 3 : View

@Model HandleErrorInfo 
@{
    ViewBag.Title = "Sorry, there was a problem!";
}

<p>
    There was a <b>@Model.Exception.GetType().Name</b>
    while rendering <b>@Model.ControllerName</b>'s
    <b>@Model.ActionName</b> action.
</p>
<p>
    The exception message is: <b><@Model.Exception.Message></b>
</p>
<p>Stack trace: @Model.Exception.StackTrace</p>

In the view we have accepted the Model HandleErrorInfo. The HandleError filter not only returns Error View but also it creates and passes the HandleErrorInfo model to the View. This Model contains details about exception, controller and action name where this exception occured.

Step 4 : Web.config

The handle error filter works only if the <customErrors mode="On" /> is on in web.config.
Thus follwing the above steps we can handle the excpetion using HandleErrorAttribute.
HandleErrorAttribute class :
public class HandleErrorInfo
{   
    public HandleErrorInfo(Exception exception, string controllerName, 
        string actionName);
 
    public string ActionName { get; }
 
    public string ControllerName { get; }
 
    public Exception Exception { get; }
}

The above class is the definition of HandleErrorInfo Model which is passed to the View.

The HandleErrorAttribute has some limitations. We have listed the limitations as below :


1. Not support to log the exceptions. 

2. Doesn't catch HTTP exceptions other than 500. 
3. Doesn't catch exceptions that are raised outside controllers.
4. Returns error view even for exceptions raised in AJAX calls.

SnapShots :




In the above screenshot, we are sending 5 as parameter which will cause NullReference exception to raise in the action method and error view is returned.

Resulted View :



No comments:

Post a Comment