Wednesday 22 August 2012

Custom Handle Error Attribute to handle exception in MVC 3 app


Frnds.
In this post I am going to explain, How can we handle error in MVC  application through common custom error attribute.
First create the custom Error Handler Attribute class. So here is our attribute class:
 public class HandleExceptionAttribute : FilterAttribute, IExceptionFilter
    {
        public void OnException(ExceptionContext filterContext)
        {
            filterContext.ExceptionHandled = true;

            string controllerName = filterContext.RouteData.Values["controller"].ToString();
            string actionName = filterContext.RouteData.Values["action"].ToString();
            string exceptionMessage = string.Empty;

            //You may not need this tracing code. Ignore it!
            Trace.TraceError("Controller = {0} : Action = {1} : Message = {2} : StackTrace = {3}",
                controllerName,
                actionName,
                filterContext.Exception.Message,
                filterContext.Exception.StackTrace);

            //Below is the switch case to handle error for all the controller class in our
            //MVC application at one place.
            switch (controllerName)
            {
                case "State":
                    switch (actionName)
                    {
                        case "Create":
                            actionName = "Index";
                            exceptionMessage = "Sorry, an error occured on creating new State, Please try again.";
                            break;
                        case "Edit":
                            actionName = "Index";
                            exceptionMessage = "Sorry, an error occured on editing new State, Please try again.";
                            break;
                        case "Delete":
                            actionName = "Index";
                            exceptionMessage = "Sorry, an error occured on deleting new State, Please try again.";
                            break;
                        default:
                            break;
                    }
                    break;
                case "Account":
                    switch (actionName)
                    {
                        case "Register":
                            controllerName = "Register";
                            actionName = "Index";
                            exceptionMessage = "Sorry, an error occured on registering new User, Please try again.";
                            break;
                        case "Login":
                            controllerName = "Login";
                            actionName = "Index";
                            exceptionMessage = "Sorry, an error occured on Login, Please try again.";
                            break;

                    }

                    break;
            }

            //Creating ViewData Dictionary which will hold the error info to show to the end user.
            ViewDataDictionary viewData = new ViewDataDictionary();
            viewData.Add(new KeyValuePair<string, object>("controller", controllerName));
            viewData.Add(new KeyValuePair<string, object>("action", actionName));
            viewData.Add(new KeyValuePair<string, object>("message", exceptionMessage));

            //Calling error page inside shared folder to show the proper error message.
            filterContext.Result = new ViewResult { ViewName = "Error", ViewData = viewData };
        }
    }
Above attribute will help to handle error. You can add your controller and action method in switch case
statement as per your need.

Now Next step we will see how to use this attribute.
        [HandleException]
        public ActionResult Edit(StateModel stateModel)
        {
            try
            {
                // TODO: Add update logic here
                throw new InvalidOperationException();
            }
            catch(Exception ex)
            {
                throw ex;
            }
        }
Since my Custom Error Handler Attribute  is written to handle error for each action of controller so I need to use it before my action method. In above code [HandleException] attribute  will execute our Custom Handle Attribute class code written here in case of any error.
Next step we need to modify/create the error  page (Error.cshtml) inside shared folder to show the error message to the end user.
@{
    ViewBag.Title = "Error";
}

<h2>
    Sorry, @ViewData["message"].<br />
    <a href="@Url.Action(ViewData["action"].ToString(),ViewData["controller"].ToString())">Back</a>
</h2>
Note: Modify the above code as per your need and enjoy.
Thank You for reading.

No comments:

Post a Comment