Few ways of Handling Exceptions in ASP.NET MVC

Exception handling is one of the major areas of an application development and when it is a web application, it requires additional care so that errors gets handled gracefully without breaking the complete system and relevant information is shown to the users with proper error message. Also making sure that no internal details gets propagated till user when application crashes or error occur because it could be a major security threat. All the exception details and other additional information should be logged so that it can be later used for proper investigation. In this post we will talk about the few options available to handle the exception in ASP.NET MVC and best practices to use them.

In ASP.NET MVC, the request first hits the route handler which identifies the controller and action to be serving the request. We put the whole logic in our controller itself. There are various type of filters in ASP.NET MVC that are also part of the request processing and some time we extend them to put some custom logic based on specific requirement. There is an Exception filter for handling exceptions as well and this Filter is key in handling exceptions in MVC. First let’s see available filters and their order of execution in request processing flow

orderoffilters

So we can see here that there are four filters in total and exception filter executes at end. It means if we use exception filter then it will be caught there whether the exception occurs in Action or even in Authorization/Action/Result filters.

Note – Filters are added as an attribute so it also inherits from ‘System.Attribute’.

Broadly we can say that exceptions may occur in controller or in some cases while processing the routes and filters. But as most of our core logic resides in action so the chances in are most. Before focusing on filters, let’s first discuss one basic way to handle to exception that is part of C#.

Using Try/Catch block

This is C# feature and one of the basic ways to handle exceptions so we can wrap all our code in our Action as below.

try
{
    // Add your code here
}
catch
{
    // Exception Handling code
} 

But there are many issues with this approach and the primary issue is the limitation to single Action. To handle that, we need to put try catch block in each Action of the application which is repeating the same exception handling code which defies the code re-usability logic. It does not mean that we should never use it but there are some scenarios where we require to perform some another activity in case of exception without letting the user know or more specifically if you are calling to some third part services etc. then it might be a good Idea to use this approach.

Global Error Handling

Global error handling is one of the simplest way to handle exceptions at application level. It leverages the Exception Filter to handle exception and applies at application level itself. This is out of the box feature and can be easily set up by following step.

  1. Set customErrors errors as On in web.config as
    <customErrors mode="On"></customErrors>
  2. Have a common error view (in Shared folder with name error.cshtml) which will be shown in case of error aserrorviewHere we see that we get a model of type HandleErrorInfo class which provides the details about that error occurred, controller and action name etc.
  3. Make sure we registere HandleErrorAttribute in Application_Start (Global.asax)method
    RegisterGlobalFilters(GlobalFilters.Filters);
    
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
         filters.Add(new HandleErrorAttribute());
    }
    

    Now if any error occurs then error view will be shown.

Customizing global error handling

We have seen that how easily we can configure the error handling at application level. But what if we want to handle it bit differently. Say we want to save the details in database and/or want to send the email notification when error occurs. We have two options here

  1. Override OnException method :

    We can override OnException method as in our controller as

    protected override void OnException(ExceptionContext filterContext)
    {
        Exception ex = filterContext.Exception;
        // Log Exception ex in database
    
        // Notify  admin team
    
        filterContext.ExceptionHandled = true;
    
        // Setting the View in case of error
        filterContext.Result = new ViewResult()
        {
            ViewName = "CustomErrorView"
        };
    }
    

    Here we can log our exception, send the mail etc. and set our own view that will be shown (like here I used CustomErrorView) in case of error. But this code won’t be reusable and need to write in each controller wherever we need.

  2. To handle it in better way, we need to extend HandleErrorAttribute as
    public class MyCustomHandleErrorAttribute : HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
                       Exception ex = filterContext.Exception;
                	     // Log Exception ex in database
    
                	     // Notify  admin team
    
                	     filterContext.ExceptionHandled = true;
    
    
            filterContext.ExceptionHandled = true;
    
            filterContext.Result = new ViewResult()
            {
                ViewName = "DVZ"
            };
        }
    }
    

    And instead of registering the default HandleErrorAttribute we need to register the custom one as

    filters.Add(new MyCustomHandleErrorAttribute());
    

    Now this custom error attribute will be used in the whole application.

Handling exception at more Granular level

Till now, we have seen that how can we apply filter at global level. MVC allows us to handle exceptions at more granular level similar at controller and action level as
granularexceptions

For Controller either we can use the default HandleErrorAttribute or we can use the extended attribute similar to MyCustomHandleErrorAttribute and put it at controller as

[MyCustomHandleError]
public class EventController : Controller
{
// Controller code
  	…
}

For Action

public class EventController : Controller
{
	[MyCustomHandleError]
public ActionResult About()
{
	// Action code
}
…
}

Note – Here I have put ‘MyCustomHandleError’ as an attribute. We can use default ‘HandleError’ attribute instead of custom one.

Another variation

There may be some scenarios where we may need to show specific view or details based on the type of exception occurs in Controller/Action. In other words, say if in Controller/Action, if a specific exception occurs, then showing user one view and any other exception occurs then show a different view. Let’s see an example

[HandleError(ExceptionType = typeof(DivideByZeroException), View = "DVZ")]
[MyCustomHandleError]
public ActionResult Create()
{
	// Action code
}

Here if DivideByZeroException occurs then view DVZ will be loaded else default one would be loaded. We can add as many type of exception based on requirement. Also similarly we can apply at Controller level as well.

ExceptionHandled property usage

In OnException method, you must have seen the following line many times.

filterContext.ExceptionHandled = true;

As the name suggests that when we set it true (default: false), then the exception does not propagate further and it is handled in the same method. Say we have put the Exception Filter at action, added a Global exception filer and we did not set the ExceptionHandled filter or set it false then once the exception is caught by action level exception filter that will be thrown further to next level and caught at global filter. Normally when we handle exception we make it false because we have already handled the exception. But there could be few scenarios where we do something with exception details and throw it further so accordingly we need to set this property.

Exception handling outside the scope of MVC

Exceptions are bound to happen and it can always find the way to reach user. We need to block every route. As we know handled the exceptions using MVC framework features but if something happens outside of the MVC scope. As we know that MVC framework is built on top of the ASP.NET platform then we can use the Application_Error method that is available since beginning to handle Application level error. It can be depicted pictorially as
aspnetnmvc

Here we can see that once the control reaches ASP.NET platform, this method can help us so we should handle the exception here as well and we can put all the logging and notification code here as

protected void Application_Error()
{
    Exception ex = Server.GetLastError();
    // Log Exception ex in database

    // Notify  admin team

    // Clear the error
    Server.ClearError();

    // Redirect to a landing page
    Response.Redirect("home/index");
}

Note: Application_Error should not be used in replacement MVC global exception filer, because as soon as you get out of MVC scope, you won’t get its execution context which is very important to provide the relevant details about the exception.

Conclusion

We have discussed various possible ways of handling exceptions. We find that all the exception handling moves around the handle error attribute with many variations. Another two that we discussed: using try catch block and using Application_Error. Best solution for any application would be a combination of these approaches like extend HandleErrorAttribute based on the requirement and use it accordingly. Application Error should be used as if an exception somehow find its way to get out from MVC scope, then it will be caught here. Try Catch block should be really avoided as it just not makes the code ugly but we can miss lots of relevant information that may be helpful in fixing the issue so unless specific case, do not use it.

ASP.NET MVC and Angular Routing together – Part 11

[To view earlier posts of the series – Click Here]
This will be short but very helpful post. I have seen lots of questions and confusion over Angular Routing and ASP.NET MVC Routing. In this post, I will try to unravel. We all already know the following two points

1- ASP.NET MVC is a server side technology so it means ASP.NET MVC routing takes place at Server.

2- AngularJS is a client side technology so Angular routing itself cannot conflict with ASP.NET MVC in any way. But it works on the top of the ASP.NET MVC. Let’s discuss it with a example.

I will be taking the sample from one of my earlier posts (Learning {{AngularJS}} with ASP.NET MVC – Part 5) on AngularJS and modify a bit for this post. Let me brief about the\example

1- It has one MVC controller – named EventsController that has three methods. One returns the index view and in rest of the two, one returns a list of talks and other, list of speakers in JSON format.

2- It has two angular routes, one for listing speakers (/Events/Speakers) and another from listing talks (/Events/Talks). These urls are used in top menu. So when we run the application and the url (http://localhost:/ or http://localhost:/events or http://localhost:/events/index) the page loads as homeAfter clicking the the two tabs talks or speakers are loaded accordingly. Angular Routes in the sample are defined as

var eventModule = angular.module("eventModule", []).config(function ($routeProvider, $locationProvider) {
 //Path - it should be same as href link
 $routeProvider.when('/Events/Talks', { templateUrl: '/Templates/Talk.html', controller: 'eventController' });
 $routeProvider.when('/Events/Speakers', { templateUrl: '/Templates/Speaker.html', controller: 'speakerController' });
 $locationProvider.html5Mode(true);
 });

Now if we access the direct angular defined routes (like ) it does not work. Let’s understand why?

When we access the url http://localhost:48551/events/index then it actually calls the MVC EventsController and Index action as expected and loads the page. Now when we click on one of the tabs (say speaker) then Angular chips in and it loads the angular view. The call does not go to MVC controller and action at server rather it gets handled at client side by Angular. It loads the data via angular service that initiates the ajax call to server to get the data. Here the url changes but handled at client side only and server (or say ASP.NET MVC) does not even get to know about it.

Now the next question, in second case, why the call does not go at server? In first case, there is nothing available at client side and request goes to the server and gets the page. When page loads it loads everything including angular library. Now when second time, the url gets changed Angular checks whether it can handle the url if yes then it just process it at client side and if not then try to load otherwise url if defined else loads nothing and leave it empty. The whole process can be defined it pictorially

ngrouteupdatedNow we can imagine a scenario while accessing a Angular defined url (http://localhost:48551/Events/Talks) as initial request, it finds nothing at client side which can handle it as it is a fresh request. And it goes to server and tries to find the EventsController and Talks action but it is not defined by ASP.NET MVC so it does not work. We just have Index action at MVC controller. Now how to resolve this issue?

As Initially in this post, I pointed out that Angular defined urls are handled at Client side only, so AngularJS must be loaded and initialized before it can handle the request. There would be two steps involved

1- All angular defined urls should be mapped to a MVC route that returns the response to client with all the client side libraries including Angular.

2- Then as angular is initialized, it handles the url as discussed earlier When we try to access an angular defined urls as first request, it goes to server then we need to initialize the page first with AngularJS then rest angular takes care.It means that in the example, we need to call the index action when somebody try to access the AngularJS urls (Talks and Speakers) directly which will load the page and it will initialize the Angular as well then the Angular urls will be handled by angular itself. So how to do that, we just need to add some routes in Global.asax of so that even if Angular defined urls are called it returns fires of the index action only. So we can add it like

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

 routes.MapRoute(
 name: "EventsCourses",
 url: "Events/Talks",
 defaults: new { controller = "Events", action = "Index", id = UrlParameter.Optional }
 );
 routes.MapRoute(
 name: "EventsSpeakers",
 url: "Events/Speakers",
 defaults: new { controller = "Events", action = "Index", id = UrlParameter.Optional }
 );

 routes.MapRoute(
 name: "Default",
 url: "{controller}/{action}/{id}",
 defaults: new { controller = "Events", action = "Index", id = UrlParameter.Optional }
 );
 }

So here I added two routes EventsCourses and EventsSpeakers for Angular Urls and for both, index action of events controller gets called.

Here we should not have a URL which can be processed by Angular and MVC both in that case you will get different behavior in both the case so we should keep in mind while defining the URLs. So I hope it must have been clear to you. Also you do not need to add each AngularURL as new route in Global.asax, you can have unique pattern in Angular URLs and for that pattern, you can have just one route which return the same action for that pattern. Sample is attached with the post.

[Update : Updated the flow diagram of this post and content to add some clarification in a scenario when requested url is not defined in URL – 04th May 15]
To navigate to previous and next post of the series, use the links at the bottom of the post.

Happy Learning
Brij

DataBinding in {{AngularJS}} – Part 7


This is the seventh post in the series of AngularJS and today, we will discuss one of the features that we already used – Data Binding in details. For earlier posts of the series, please refer the links below

Learning {{AngularJS}} with Examples–Part 1

Learning {{AngularJS}} with Examples–Part 2

Learning {{AngularJS}} with ASP.NET MVC – Part 3

Learning {{AngularJS}} with ASP.NET MVC – Part 4

Learning {{AngularJS}} with ASP.NET MVC – Part 5

Learning {{AngularJS}} with ASP.NET MVC – Part 6

Let’s just take a quick look on our picture trackerpicture-tracker

Broadly, Data binding can be divided in the two parts
– One way binding
– Two way binding

Continue reading

Remove ViewEngines that are not used : An ASP.NET MVC performance tip

Today, I am writing a small post on ASP.NET MVC that will help in performance of ASP.NET MVC application. So lets discuss it in detail.

Whenever we create an ASP.NET MVC application it allows us to select a View Engine Razor for the application as.

select View engine

Here we selected Razor and this is selected by default as well.

But when applications run, it loads multiple view engines and we use only one view engine normally that is selected while application creation. We can prove it many ways

1) Let’s see the collection ViewEngines in Global.asax. It shows as while debugging.

firstallThe above clearly shows that it contains two View Engines while we selected Razor View Engine while creating application.

2) To prove it another way, As we know when we use Razor View Engine then views extension is .cshtml and for WebForms view engine, it is .aspx. So lets say we created a controller and it has a method like

public ActionResult Index()
{
    return View();
}

And we did not created any view accordingly. Now when we run the applications it throws the following error

serachedviews

It tries to find the View but could not find. It also shows what file names and where does it try to find. If we see the above screenshot then we find that it tries to look files with extension .cshtml/.vbhtml and .aspx/.ascx as well, where .aspx/.ascx is used in case of web-forms view engine. And we selected razor View engine while application creation. It simply shows that it loads two view  engines which is not required.

Solution : Add the following code in the method Application_Start in Global.asax

// Removes all the view engine
ViewEngines.Engines.Clear();

// Add View Engine that we are ging to use. Here I am using Razor View Engine
ViewEngines.Engines.Add(new RazorViewEngine());

Now after making the above changes, it loads only the added ( here Razor) view engine.

Now we can check the scenario discussed in point 2 and now see the page

afterremovinNow it tries to find only .cshtml/.vbhtml files.

We should use the above logic and because there is no use loading all the view engines in memory if we are not using .

Hope you all find it useful and use it in your projects.

Cheers,
Brij

Learning {{AngularJS}} with ASP.NET MVC – Part 6

It’s been around a month since I wrote the fifth part of the series on AngularJS. We have covered a bunch of concepts in our last five posts. I will advise to go first the earlier posts then continue reading it. Links of my earlier posts on this series are.

Learning {{AngularJS}} with Examples–Part 1

Learning {{AngularJS}} with Examples–Part 2

Learning {{AngularJS}} with ASP.NET MVC – Part 3

Learning {{AngularJS}} with ASP.NET MVC – Part 4

Learning {{AngularJS}} with ASP.NET MVC – Part 5

In our last post, we created a sample where we had a page that comprised two views : Talk details and Speaker Details. We fetched two sets of data (Talks and Speakers) from server via  AJAX call and rendered on the page using templates with the help of Angular rendering engine. In this application, we are going to use again the same application and add some more features which are relevant in our day to day coding.

In today’s post, we will use almost the same concepts that we discussed in our last post but use it for different scenario. Let’s put our picture tracker.

trackerHere I highlighted four components and we had already used it one or other ways in earlier posts. But we’ll discuss the new highlighted components briefly here as well.

Continue reading

Learning {{AngularJS}} with ASP.NET MVC – Part 5

This is the fifth part in the series of AngularJS. We have discussed the basic components of AngularJS in our earlier posts. Please find the links of my earlier post on this series as

 Learning {{AngularJS}} with Examples–Part 1

Learning {{AngularJS}} with Examples–Part 2

Learning {{AngularJS}} with ASP.NET MVC – Part 3

Learning {{AngularJS}} with ASP.NET MVC – Part 4

So let’s move to series tracker and see what are we going to learn today.

structuctureSo far, we have discussed five main components. Today we will be discussing Views and Routing.

Continue reading

Learning {{AngularJS}} with ASP.NET MVC – Part 4


This is fourth part in the series on AngularJS and till now we have discussed some basic components and used those in our examples.The links of my earlier post on this series are

Learning {{AngularJS}} with Examples–Part 1

Learning {{AngularJS}} with Examples–Part 2

Learning {{AngularJS}} with ASP.NET MVC – Part 3

So what will we be covering today. Let’s see our picture tracker

image

In our earlier posts in the series, we discussed five components. As we see in the above image, in this post, we will discuss services again. Angular services is vast topic but I am discussing the important concepts. One of the important technology that we use in a web applications is AJAX. So in today’s post our focus would that how AngularJS enables us to use AJAX.

Continue reading