Click here to Skip to main content
15,860,859 members
Articles / General Programming / Exceptions

Exception Handling in MVC

Rate me:
Please Sign up or sign in to vote.
4.76/5 (76 votes)
4 Dec 2014CPOL4 min read 337.4K   141   21
Supporting article for MVC step by step series. Here we will see detail demonstration on exception handling.

<w:sdt docparttype="Table of Contents" docpartunique="t" id="-2057686482" sdtdocpart="t">

Contents

Introduction

In this article we will discuss about Exception handling in MVC in detail. If you are completely new to MVC then please read day 1 from our MVC step by step article.

Initial setup for our lab

Before we go and start our step by step demo on exception handling lets create a sample demo.


Image 1

Local level Exception Handling

1. Simply Try…Catch approach

public ActionResult TestMethod()
{
    try
    {
        //....
        return View();
    }
    catch (Exception e)
    {
        //Handle Exception;
        return View("Error");
    }
}

Limitation:

Problem with the above approach is we cannot reuse the exception handling logic across multiple action methods. That where our second approach comes to picture.

2. Override OnException method in controller

protected override void OnException(ExceptionContext filterContext)
{
    Exception e = filterContext.Exception;
    //Log Exception e
    filterContext.ExceptionHandled=true;
    filterContext.Result = new ViewResult()
    {
        ViewName = "Error"
    };
}

Advantage

Now we can share error handling logic across all the actions in a controller

Limitation:

Problem with the above approach is we cannot reuse the exception handling logic across multiple controllers. That where global error handling comes to picture.

Global level Exception Handling

Step 1

In Web.Config simply enable custom error as follows and execute our application.

<customerrors mode="On" />
Output

Image 2

It seems that only step 1 done all the work, but how? We have not specified the error page (view) name anywhere, still in response we get error view whenever error occurs.
Let’s understand how?

FilterConfig class

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }
}

As you can see HandleErrorAttrubute is added to global filter collection.

Where RegisterGlobalFilters method is invoked?

In Global.asax file in Applicaion_Start RegisterGlobalFilters method is invoked.

Image 3

What it does?

It handles all the exceptions raised by all action methods in all the controllers and return error view present inside shared folder.

HandleError at controller level?

  1. Remove the code written in FilterConfig class
  2. Add HandleErrorAttribute to Controller class as follows,
Image 4

Now errors raised by all action methods present inside TestingController method will be handled. Other exceptions will be considered as unhandled exceptions.

HandleError at Action level

Add HandleErrorAttribute to Action method as follows,

Image 5

Displaying error detail in Error view

For that we will make our error view strongly typed view of model System.Web.Mvc.HandleErrorInfo and then as usual using @Model keyword we can access the members. One of the member is Exception object.

Image 6

Different views for Different Exceptions

For that we will use overloaded version of HandleErrorAttribute constructor as follows.

Image 7

Limitations of HandleErrorAttribute

  1. Error won’t get logged anywhere.
  2. Exceptions raised outside controllers will not be handled. Example- exception raised because of invalid url won’t be handled.
  3. Exception Handling based on scenario is not possible. Example – So one error page when request comes via ajax and different one when comes via normal request.

Extending HandleErrorAttribute

Some of the above limitations can be overcame by extending the default HandleErrorAttribute as follow.

private bool IsAjax(ExceptionContext filterContext)
{
    return filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest";
}
public override void OnException(ExceptionContext filterContext)
{
    if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
    {
        return;
    }
 
    // if the request is AJAX return JSON else view.
    if (IsAjax(filterContext))
    {
        //Because its a exception raised after ajax invocation
        //Lets return Json
        filterContext.Result = new JsonResult(){Data=filterContext.Exception.Message,
            JsonRequestBehavior=JsonRequestBehavior.AllowGet};
 
        filterContext.ExceptionHandled = true;
        filterContext.HttpContext.Response.Clear();    
    }
    else
    {
        //Normal Exception
        //So let it handle by its default ways.
        base.OnException(filterContext);
                
    }
 
    // Write error logging code here if you wish.

    //if want to get different of the request
    //var currentController = (string)filterContext.RouteData.Values["controller"];
    //var currentActionName = (string)filterContext.RouteData.Values["action"];
}

Advantages of extending Handle Error Attribute

  1. Now we can log errors.
  2. More control over exception handling. Now we have full control over exception handling code so we can simply check whether it’s an Ajax request or normal request and proceed accordingly.

“Resource cannot be found” Exception

This is the one which cannot be handled by neither HandleErroAttribute nor CustomHandleErrorAttribute.

But we can follow the traditional web.config approach as follows.

<customerrors mode="On">
  <error statuscode="404" redirect="~/Testing/NoPageFound">
</error></customerrors>

How Global level HandleErrorAttribute is different from Application_Error?

Application_Error is an application level event, we define in the global.asax file. It will be executed whenever there is an unhandled exception in the application.
If this is the point, why we won’t use Application_Error always?

Here are the advantages of HandleError over Application_Error,

  1. With HandleErrorAttribute we get more control over exception handling. HandleError allow us to handle error differently for different controllers and actions easily where in Application_Error to get this feature we take the help of switch loop.
  2. Once you are into Application_Error you are out of MVC and you will lose ControllerContext and then we cannot do much things which will easily possible with HandleError.

To learn MVC start from the below YouTube video which teaches MVC 5 in 2 days i.e. 16 hours.

<w:sdt docparttype="Table of Contents" docpartunique="t" id="-2057686482" sdtdocpart="t">

<w:sdt docparttype="Table of Contents" docpartunique="t" id="-2057686482" sdtdocpart="t">

<w:sdt docparttype="Table of Contents" docpartunique="t" id="-2057686482" sdtdocpart="t">

<w:sdt docparttype="Table of Contents" docpartunique="t" id="-2057686482" sdtdocpart="t">

Image 8

Thanks for reading. Hope you have enjoyed reading this article. In case you are interested in any technical training related to MVC, WCF, Design Patterns, WPF, Angular.js, TFS,UML or BI visit www.sukesh-Marla.com or contact SukeshMarla@Gmail.com

See 600+ above FAQ questions and answers in .NET, C#, ASP.NET, SQL, WCF, WPF, WWF, SharePoint, Design patterns, UML etc.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Founder Just Compile
India India
Learning is fun but teaching is awesome.

Who I am? Trainer + consultant + Developer/Architect + Director of Just Compile

My Company - Just Compile

I can be seen in, @sukeshmarla or Facebook

Comments and Discussions

 
GeneralMy vote of 5 Pin
Victor Bastidas2-Aug-17 15:15
Victor Bastidas2-Aug-17 15:15 
PraiseMy vote 4 Pin
Arkadeep De27-Feb-17 19:40
professionalArkadeep De27-Feb-17 19:40 
QuestionMy vote 3 Pin
EsseyG16-Aug-16 0:30
professionalEsseyG16-Aug-16 0:30 
Questiongood patterns Pin
kiquenet.com4-Apr-16 12:27
professionalkiquenet.com4-Apr-16 12:27 
SuggestionNice Article for beginners Pin
awaneesh jatrana13-Oct-15 5:24
awaneesh jatrana13-Oct-15 5:24 
QuestionMy vote of 4 Pin
Sung M Kim23-Jul-15 5:55
professionalSung M Kim23-Jul-15 5:55 
AnswerRe: My vote of 4 Pin
Marla Sukesh23-Jul-15 19:49
professional Marla Sukesh23-Jul-15 19:49 
GeneralMy vote of 5 Pin
Tamal Patra29-Dec-14 20:04
Tamal Patra29-Dec-14 20:04 
GeneralRe: My vote of 5 Pin
Marla Sukesh1-Jan-15 18:08
professional Marla Sukesh1-Jan-15 18:08 
SuggestionHandle error in BaseController Pin
Pankaj.Singh2317-Nov-14 0:15
Pankaj.Singh2317-Nov-14 0:15 
GeneralRe: Handle error in BaseController Pin
Ahmed Bakodah6-Dec-14 2:36
Ahmed Bakodah6-Dec-14 2:36 
GeneralRe: Handle error in BaseController Pin
Marla Sukesh1-Jan-15 18:14
professional Marla Sukesh1-Jan-15 18:14 
GeneralMy vote of 5 Pin
RogerGlez4-Sep-14 5:53
RogerGlez4-Sep-14 5:53 
AnswerGood post Pin
Uddhav Garkal29-Jul-14 20:55
Uddhav Garkal29-Jul-14 20:55 
GeneralMy vote of 4 Pin
Assil19-Jul-14 7:28
professionalAssil19-Jul-14 7:28 
GeneralRe: My vote of 4 Pin
Marla Sukesh20-Jul-14 4:34
professional Marla Sukesh20-Jul-14 4:34 
GeneralMessage Closed Pin
30-Jun-14 1:18
Binu198530-Jun-14 1:18 
QuestionClassic foobar Pin
JVRO7-Jun-14 22:04
JVRO7-Jun-14 22:04 
QuestionWithholding my vote Pin
Ed Gadziemski10-Mar-14 18:06
professionalEd Gadziemski10-Mar-14 18:06 
GeneralMy vote of 5 Pin
Gaston Verelst24-Feb-14 3:26
Gaston Verelst24-Feb-14 3:26 
GeneralRe: My vote of 5 Pin
Marla Sukesh24-Feb-14 5:27
professional Marla Sukesh24-Feb-14 5:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.