Saturday, 19 March 2016

Let us Learn Tuple-Part1

Chandan Kumar
shared this article with you from Inoreader

C#4.0 has introduced a new feature call Tuple.In this article we will start learning about Tuple, how to create it,when to use Tuple and how to access Tuple.

Introduction

C#4.0 has introduced a new feature call Tuple. In this article we will start learning about Tuple, how to create it, when to use Tuple and how to access Tuple. This is a series of articles on Tuples and you can read the entire series of article as listed down

Let us Learn Tuple-Part1

Let us Learn Tuple-Part2 ( Creation of Generic Collections and Accessing the same using Tuple )

Let us Learn Tuple-Part3 ( Tuple and Arrays )

Let us Learn Tuple-Part4 ( Create MultiKey dictionary using Tuple )

Let us Learn Tuple-Part5 ( LAMBDA with Tuple )

Let us Learn Tuple-Part6 (Tuple Serialization and DeSerialization)

Let us Learn Tuple-Part7 (Last but not the least part)

(A)What is Tuple?

Tuple is an ordered sequence data structure, introduced in C#4.0, that holds heterogeneous objects. It is represented both as an instance class as well as a static class that uses a static method call Create to create item(s) at runtime. The items(s) created by the Create method is also a Tuple. In other words, the Create static method of the Tuple static class returns an instance of a Tuple.

The Create method has eight(8) overloaded method as shown under

public static class Tuple  {  public static Tuple<T1> Create<T1>(T1 item1);  public static Tuple<T1, T2> Create<T1, T2>(T1 item1, T2 item2);  public static Tuple<T1, T2, T3> Create<T1, T2, T3>(T1 item1, T2 item2, T3 item3);  public static Tuple<T1, T2, T3, T4> Create<T1, T2, T3, T4>(T1 item1, T2 item2, T3 item3, T4 item4);  public static Tuple<T1, T2, T3, T4, T5> Create<T1, T2, T3, T4, T5>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5);  public static Tuple<T1, T2, T3, T4, T5, T6> Create<T1, T2, T3, T4, T5, T6>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6);  public static Tuple<T1, T2, T3, T4, T5, T6, T7> Create<T1, T2, T3, T4, T5, T6, T7>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7);  public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>> Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8);  }  

As can be figure out that, the last argument is again another tuple. This clearly reveals that we can add another tuple item in the 8th argument.

It resides under the System namespace.

(B)Why Tuple?

We know that any called function returns a single value. However, there are times where we may need to return multiple values to the calling function. Tuple precisely serves that purpose.

Let us observe the above statement with an example.

static Tuple<List<int>, List<int>> GetEvenOddNumbers()  {      var numbers = Enumerable.Range(1, 20); //generate numbers between 1 to 20      return           Tuple          .Create          (            numbers.Where(i=>i%2==0).ToList() //find even numbers list            , numbers.Where(i => i % 2 != 0).ToList() //find odd numbers list          );  }  

In the above function, we are generating a series of numbers between 1 to 20 and then segregating the even and odd numbers list and finally returning the same by using Tuple. We can figure out that, the Tuple returns two values of type List<int>, List<int>.This indicates that, the function GetEvenOddNumbers() is capable of returning more than one value to the calling function.

(C)When to use Tuple?

Tuples finds it's usage in multiple places. Some of them are listed below

1. Return multiple values from a method or function

In earlier versions of dotnet(before 4.0), we can achive to return multiple values from a function by using OUT parameters e.g

class MainClass  {          public static void Main(string[] args)          {              var evenNumList = new List<int>();              var oddNumList = new List<int>();                GetEvenOddNumbersUsingOutParameters(out evenNumList, out oddNumList);                        }            private static void GetEvenOddNumbersUsingOutParameters(out List<int> evenNumList,                                                                   out List<int> oddNumList)          {              var numbers = Enumerable.Range(1, 20); //generate numbers between 1 to 20              evenNumList = numbers.Where(i => i % 2 == 0).ToList();              oddNumList  = numbers.Where(i => i % 2 != 0).ToList();          }            }   

Some disadvantages of the above program can be listed as under

  1. Declaration and initialization of extra variables which on the other hand indicates more space complexity and unnecessary object creation.
  2. Using OUT parameter breaks the Single Responsibility Principle
  3. It is slower to access since it involves double indirection problem.

For a better design perspective, we can create a Custom class and use it to return multiple values from a function. But this approach has it's own limitation as it may not be equally feasible all the time to do so and moreover can cause extra code size.

Another approach can be a collection like Dictionary, HashTable or ArrayList but again a seek time for the look-up is involve

And the most common disadvantage to all of the above approach is that they are not thread safe since they are instance members of some kind as opposed to Tuple since it is static and so are it's member(s)

2. Passing multiple values from calling function to a called function

Let us consider the below example

public static void Main(string[] args)  {                           var names = new List<string>() { "Name1", "Name2", "Name3", "Name4" };              var index = new List<int>() { 1, 2, 3, 4 };              var nameIndexTuple  = new Tuple<List<string>, List<int>>(names, index);              ShowItemPosition(nameIndexTuple);             }    private static void ShowItemPosition(Tuple<List<string>, List<int>> nameIndexTuple)  {                  //do something interesting  }  

In the above program, we have created a string and integer collection of items, bundled them inside a Tuple and finally passing them as a single parameter to the called function ShowItemPosition.

We can also achieve the same by using the above describe methods but again with the same disadvantage. Params can serve the purpose but it has it's own limitation since an array is a collection of same type. We can, however, create an object datatype param but it will be tedious to read and manipulate as it involves a huge boxing and unboxing.

Tuple on the other hand, is much more cleaner approach.

(D)How to create Tuple in C#?

We can create Tuple in one of the two below listed ways

  1. By creating a class instance of Tuple Class

    E.g.

    Tuple<string, int, List<string>> studentTupleInstance = new Tuple<string, int, List<string>>(      "Rajlaxmi", 4      , new List<string> { "Mathematics","English","Science and Social Science","Hindi"     });                    

    In the above example we have created an instance (studentTupleInstance) of the Tuple class which contains a string (Student Name),an integer (Student age) and a collection of string (Collection of Subjects). This is an example of 3-Tuple or Triple.

  2. By using the static Create method of Tuple Class

    E.g.

    Tuple<string, int, List<string>> studentTupleCreateMethod = Tuple.Create(        "Rajlakshmi", 4,          new List<string> { "Mathematics","English",                                            "Science and Social Science","Hindi"                                          });                    

    In the above example we have created the Tuple (studentTupleCreateMethod) by using the static Create method of the Tuple class which contains a string (Student Name),an integer (Student age) and a collection of string (Collection of Subjects).

(E)How to access Tuple in C#?

Accessing the items of Tuples as very simple. Tuples items or properties are of Generic Types and henceforth, they don't have any concrete names. In-order to access the Tuple items, we need to invoke the dot (.) operator preceded by the Tuple name as shown below

In the above figure, Item1 represents the first item of the Tuple ((Student Name) which is of type string.

The second item (Student age)is of type int and the last one (Collection of Subjects) is of List<string>.

Being generic, it reduced the overhead of boxing and unboxing which could be on the other hand a tedious task with Objects or Dynamics

References

Tuple Class

An introduction to Tuple

Conclusion

In this introductory article with Tuple, we learnt about What a Tuple is Why we need Tuple, When to use it, How to create Tuple and How to access the same in C#. Hope this will be helpful. More to come in the following series. Zipped file attached.

View on the web
Inoreader is a light and fast RSS Reader. Follow us on Twitter and Facebook.

Let us Learn Tuple-Part1

Chandan Kumar
shared this article with you from Inoreader

C#4.0 has introduced a new feature call Tuple.In this article we will start learning about Tuple, how to create it,when to use Tuple and how to access Tuple.

Introduction

C#4.0 has introduced a new feature call Tuple. In this article we will start learning about Tuple, how to create it, when to use Tuple and how to access Tuple. This is a series of articles on Tuples and you can read the entire series of article as listed down

Let us Learn Tuple-Part1

Let us Learn Tuple-Part2 ( Creation of Generic Collections and Accessing the same using Tuple )

Let us Learn Tuple-Part3 ( Tuple and Arrays )

Let us Learn Tuple-Part4 ( Create MultiKey dictionary using Tuple )

Let us Learn Tuple-Part5 ( LAMBDA with Tuple )

Let us Learn Tuple-Part6 (Tuple Serialization and DeSerialization)

Let us Learn Tuple-Part7 (Last but not the least part)

(A)What is Tuple?

Tuple is an ordered sequence data structure, introduced in C#4.0, that holds heterogeneous objects. It is represented both as an instance class as well as a static class that uses a static method call Create to create item(s) at runtime. The items(s) created by the Create method is also a Tuple. In other words, the Create static method of the Tuple static class returns an instance of a Tuple.

The Create method has eight(8) overloaded method as shown under

public static class Tuple  {  public static Tuple<T1> Create<T1>(T1 item1);  public static Tuple<T1, T2> Create<T1, T2>(T1 item1, T2 item2);  public static Tuple<T1, T2, T3> Create<T1, T2, T3>(T1 item1, T2 item2, T3 item3);  public static Tuple<T1, T2, T3, T4> Create<T1, T2, T3, T4>(T1 item1, T2 item2, T3 item3, T4 item4);  public static Tuple<T1, T2, T3, T4, T5> Create<T1, T2, T3, T4, T5>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5);  public static Tuple<T1, T2, T3, T4, T5, T6> Create<T1, T2, T3, T4, T5, T6>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6);  public static Tuple<T1, T2, T3, T4, T5, T6, T7> Create<T1, T2, T3, T4, T5, T6, T7>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7);  public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>> Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8);  }  

As can be figure out that, the last argument is again another tuple. This clearly reveals that we can add another tuple item in the 8th argument.

It resides under the System namespace.

(B)Why Tuple?

We know that any called function returns a single value. However, there are times where we may need to return multiple values to the calling function. Tuple precisely serves that purpose.

Let us observe the above statement with an example.

static Tuple<List<int>, List<int>> GetEvenOddNumbers()  {      var numbers = Enumerable.Range(1, 20); //generate numbers between 1 to 20      return           Tuple          .Create          (            numbers.Where(i=>i%2==0).ToList() //find even numbers list            , numbers.Where(i => i % 2 != 0).ToList() //find odd numbers list          );  }  

In the above function, we are generating a series of numbers between 1 to 20 and then segregating the even and odd numbers list and finally returning the same by using Tuple. We can figure out that, the Tuple returns two values of type List<int>, List<int>.This indicates that, the function GetEvenOddNumbers() is capable of returning more than one value to the calling function.

(C)When to use Tuple?

Tuples finds it's usage in multiple places. Some of them are listed below

1. Return multiple values from a method or function

In earlier versions of dotnet(before 4.0), we can achive to return multiple values from a function by using OUT parameters e.g

class MainClass  {          public static void Main(string[] args)          {              var evenNumList = new List<int>();              var oddNumList = new List<int>();                GetEvenOddNumbersUsingOutParameters(out evenNumList, out oddNumList);                        }            private static void GetEvenOddNumbersUsingOutParameters(out List<int> evenNumList,                                                                   out List<int> oddNumList)          {              var numbers = Enumerable.Range(1, 20); //generate numbers between 1 to 20              evenNumList = numbers.Where(i => i % 2 == 0).ToList();              oddNumList  = numbers.Where(i => i % 2 != 0).ToList();          }            }   

Some disadvantages of the above program can be listed as under

  1. Declaration and initialization of extra variables which on the other hand indicates more space complexity and unnecessary object creation.
  2. Using OUT parameter breaks the Single Responsibility Principle
  3. It is slower to access since it involves double indirection problem.

For a better design perspective, we can create a Custom class and use it to return multiple values from a function. But this approach has it's own limitation as it may not be equally feasible all the time to do so and moreover can cause extra code size.

Another approach can be a collection like Dictionary, HashTable or ArrayList but again a seek time for the look-up is involve

And the most common disadvantage to all of the above approach is that they are not thread safe since they are instance members of some kind as opposed to Tuple since it is static and so are it's member(s)

2. Passing multiple values from calling function to a called function

Let us consider the below example

public static void Main(string[] args)  {                           var names = new List<string>() { "Name1", "Name2", "Name3", "Name4" };              var index = new List<int>() { 1, 2, 3, 4 };              var nameIndexTuple  = new Tuple<List<string>, List<int>>(names, index);              ShowItemPosition(nameIndexTuple);             }    private static void ShowItemPosition(Tuple<List<string>, List<int>> nameIndexTuple)  {                  //do something interesting  }  

In the above program, we have created a string and integer collection of items, bundled them inside a Tuple and finally passing them as a single parameter to the called function ShowItemPosition.

We can also achieve the same by using the above describe methods but again with the same disadvantage. Params can serve the purpose but it has it's own limitation since an array is a collection of same type. We can, however, create an object datatype param but it will be tedious to read and manipulate as it involves a huge boxing and unboxing.

Tuple on the other hand, is much more cleaner approach.

(D)How to create Tuple in C#?

We can create Tuple in one of the two below listed ways

  1. By creating a class instance of Tuple Class

    E.g.

    Tuple<string, int, List<string>> studentTupleInstance = new Tuple<string, int, List<string>>(      "Rajlaxmi", 4      , new List<string> { "Mathematics","English","Science and Social Science","Hindi"     });                    

    In the above example we have created an instance (studentTupleInstance) of the Tuple class which contains a string (Student Name),an integer (Student age) and a collection of string (Collection of Subjects). This is an example of 3-Tuple or Triple.

  2. By using the static Create method of Tuple Class

    E.g.

    Tuple<string, int, List<string>> studentTupleCreateMethod = Tuple.Create(        "Rajlakshmi", 4,          new List<string> { "Mathematics","English",                                            "Science and Social Science","Hindi"                                          });                    

    In the above example we have created the Tuple (studentTupleCreateMethod) by using the static Create method of the Tuple class which contains a string (Student Name),an integer (Student age) and a collection of string (Collection of Subjects).

(E)How to access Tuple in C#?

Accessing the items of Tuples as very simple. Tuples items or properties are of Generic Types and henceforth, they don't have any concrete names. In-order to access the Tuple items, we need to invoke the dot (.) operator preceded by the Tuple name as shown below

In the above figure, Item1 represents the first item of the Tuple ((Student Name) which is of type string.

The second item (Student age)is of type int and the last one (Collection of Subjects) is of List<string>.

Being generic, it reduced the overhead of boxing and unboxing which could be on the other hand a tedious task with Objects or Dynamics

References

Tuple Class

An introduction to Tuple

Conclusion

In this introductory article with Tuple, we learnt about What a Tuple is Why we need Tuple, When to use it, How to create Tuple and How to access the same in C#. Hope this will be helpful. More to come in the following series. Zipped file attached.

View on the web
Inoreader is a light and fast RSS Reader. Follow us on Twitter and Facebook.

Friday, 18 March 2016

Diagnostics in ASP.NET MVC 6 (ASP.NET Core 1.0)

Chandan Kumar
shared this article with you from Inoreader

The ASP.NET Core 1.0 release (currently in RC1) provides several new features as well as improvements to existing features. One such very useful feature is Diagnostics. ASP.NET Core a.k.a ASP.NET 5 simplifies diagnostics. In this article, we will go through the Diagnostics feature and see how to implement it in an ASP.NET MVC 6 application.

 

ASP.NET 5 is now known as ASP.NET Core 1.0. In the ASP.NET Core 1.0 release, Web API is merged with ASP.NET MVC, termed as MVC 6.

Implementing Diagnostics in ASP.NET MVC 6

This application is implemented using Visual Studio 2015 and ASP.NET Core 1.0.

Step 1: Open Visual Studio 2015 and create a new ASP.NET Web Application from Add New Project window. Click on OK and select Empty from ASP.NET 5 Templates. Click on OK to create the project.

Step 2: In this project, open the project.json file and add the following dependencies in the dependencies section

"Microsoft.AspNet.Mvc": "6.0.0-rc1-final",  "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final",  "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final",  "Microsoft.AspNet.Tooling.Razor": "1.0.0-rc1-final",  "Microsoft.Extensions.CodeGenerators.Mvc": "1.0.0-rc1-final",  "Microsoft.Extensions.Configuration.FileProviderExtensions": "1.0.0-rc1-final",  "Microsoft.Extensions.Configuration.Json": "1.0.0-rc1-final"  

This will add the necessary references in the project.

Step 3: In the project, add a Models folder and in this folder add ModelClasses.cs. Add the following code in this class file

using System.Collections.Generic;    namespace ASPNET_Core_Diagnistics.Models  {      public class Employee      {          public int EmpNo { get; set; }          public string EmpName { get; set; }      }        public class EmployeesDatabase : List<Employee>      {          public EmployeesDatabase()          {              Add(new Employee() { EmpNo = 1, EmpName = "A" });              Add(new Employee() { EmpNo = 2, EmpName = "B" });              Add(new Employee() { EmpNo = 3, EmpName = "C" });              Add(new Employee() { EmpNo = 4, EmpName = "D" });              Add(new Employee() { EmpNo = 5, EmpName = "E" });              Add(new Employee() { EmpNo = 6, EmpName = "F" });          }      }        public class DataAccess      {          public List<Employee> Get()          {              return new EmployeesDatabase();          }      }    }  

The above code contains the entity class of name Employee and the EmployeesDatabase class contains some Employee records in it. The DataAccess class contains Get() method and returns EmployeesDatabase class instance.

Step 4: In this folder, add a new folder of name Services. In the Services folder, add the class file of name Services. Add the following code in it

using ASPNET_Core_Diagnistics.Models;  using System.Collections.Generic;    namespace ASPNET_Core_Diagnistics.Services  {      public interface IService<T> where T :class      {          IEnumerable<T> Get();      }        public class EmployeeService : IService<Employee>      {          DataAccess ds;          public EmployeeService(DataAccess d)          {              ds = d;          }          public IEnumerable<Employee> Get()          {              return ds.Get();          }      }  }  

The above code contains an interface of name IService<T> where T is the type. The EmployeeService implements IService interface. The constructor of EmployeeService is injected with the DataAccess object.

Step 5: In the same project, add a Controllers folder and in this folder add a MVC Controller Class using Add > New Item > MVC Controller class. By default, the name of the controller class is HomeController, rename it to EmployeeController.

Step 6: In the Startup.cs we need to define the required configuration. We will use the inbuilt dependency injection feature of ASP.NET Core 1.0. Add the following code in the ConfigureServices() method of the Startup.cs class

public void ConfigureServices(IServiceCollection services)  {      services.AddMvc();      services.AddSingleton<IService<Employee>, EmployeeService>();  }  

Step 7: To use MVC we need to define routing for the application, add the following code in the Configure() method of the Startup class

public void Configure(IApplicationBuilder app)  {      app.UseIISPlatformHandler();        app.UseStaticFiles();      app.UseMvc(routes =>      {          routes.MapRoute(              name: "default",              template: "{controller=Employee}/{action=Index}/{id?}");      });  }  

Step 8: Now add a new folder of name Views to the project. In this folder add a new sub-folder of name Employee. In the Views folder, add a new MVC View Imports Page and add the following code in it

@using ASPNET_Core_Diagnostics;  @using ASPNET_Core_Diagnostics.Models;    @addTagHelper "*, Microsoft.AspNet.Mvc.TagHelpers"  

This will be used to execute new asp- attribute in MVC Views.

Step 9: In the Employee subfolder of Views folder, add a new MVC View of name Index.cshtml and add the following markup code in it

@model IEnumerable<ASPNET_Core_Diagnostics.Models.Employee>    @{            ViewData["Title"] = "Index";  }    <h2>Index</h2>  <table class="table">      <tr>          <th>              @Html.DisplayNameFor(model => model.EmpNo)          </th>          <th>              @Html.DisplayNameFor(model => model.EmpName)          </th>          <th></th>      </tr>        @foreach (var item in Model)      {          <tr>              <td>                  @Html.DisplayFor(modelItem => item.EmpNo)              </td>              <td>                  @Html.DisplayFor(modelItem => item.EmpName)              </td>          </tr>      }  </table>  

 

Step 10: Running the application

Run the application, the following result will be displayed

aspnet-error-500

This shows a generic Error 500, let us find out the exact error. We can do this by using Microsoft.AspNet.Diagnostics. Add this namespace in the Startup.cs. In the Configure() method add the following code (highlighted)

public void Configure(IApplicationBuilder app,IHostingEnvironment environment)  {      app.UseIISPlatformHandler();        if (string.Equals(environment.EnvironmentName, "Development", StringComparison.OrdinalIgnoreCase))      {          app.UseDeveloperExceptionPage();                 }          app.UseStaticFiles();      app.UseMvc(routes =>      {          routes.MapRoute(              name: "default",              template: "{controller=Employee}/{action=Index}/{id?}");      });    }  

The above code uses an if statement to check the EnvironmentName, this is used to verify the current mode in which the application is running. Currently we are using development mode. The UseDeveloperException() extension method is used to render the exception during the development mode.

Run the application and the following result will be displayed:

exception-page

This shows the stack trace error. In our scenario it shows the Object reference is not set to an instance of object. It shows that the foreach loop is not working. This is the problem of the Index() action method of the EmployeeController. Change the code as following

public class EmployeeController : Controller  {      IService<Employee> _service;      public EmployeeController(IService<Employee> srv)      {          _service = srv;      }      // GET: /<controller>/      public IActionResult Index()      {          var Emps = _service.Get();          return View(Emps);      }  }  

We are injecting the IService<Employee> in the EmployeeController constructor. The Index() action method is calling the Get() method of the IService.

Run the following application, the following result will be displayed

aspnet-diagnostics-dataaccess

The above error shows the Unable to resolve the DataAccess error. To resolve this, let's verify the code of EmployeeService class. In the constructor, we are passing the dependency of DataAccess but we have not registered it in the ConfgureServices() method. Add the following code in the ConfgureServices() method.

public void ConfigureServices(IServiceCollection services)  {      services.AddMvc();      services.AddScoped(typeof(DataAccess));      services.AddSingleton<IService<Employee>, EmployeeService>();  }  

We have added the DataAccess as a dependency in the application.

Run the application and the following result will be displayed:

result

And thus by using Diagnostics in ASP.NET Core 1.0, we have easily sorted out the coding issue in the application.

Download the entire source code of this article (Github)

View on the web
Inoreader is a light and fast RSS Reader. Follow us on Twitter and Facebook.

ASP.NET MVC 5: Logging Exceptions in Database

Chandan Kumar
shared this article with you from Inoreader

During application development, we should consider logically correct and incorrect code execution based on the end-users requests, or the data posted by them. Sometimes even after testing our code using various test-cases, our code may not respond correctly to the request posted by end-users. Taking view of this reality, we implement our code via exception handling techniques using try-catch-finally block. This block successfully executes for all possible known types of exceptions e.g. File IO Read/Write issues, database connectivity issues etc. But what if during a request processing, a request fails due to the resource requested not available, or data posted by the end-user fails against some business rules. In this case, a web developer has to implement custom exception handling logic for handling such exceptions. This logic should be so flexible that whenever at any point in the application, such an exception occurs, this logic should be executed and exception handled and logged for further analysis.

 

Since ASP.NET MVC sits on top of the ASP.NET Runtime, it means that an MVC application can use ASP.NET's Application_Error event. In this case, any unhandled exception by MVC can be handled by the Application_Error event of ASP.NET. This is a great approach to handle Application Level Exceptions. But the problem of such an approach is that since it is at the application level and provides a lesser specific way of handling an exception, the MVC Controller Context data is lost. This means that we are no more handling an exception in our MVC application. However our requirement here is that we need to handle all exceptions at the MVC level only.

There are some simpler ways provided in MVC for handling exception. Please visit http://www.dotnetcurry.com/aspnet-mvc/1068/aspnet-mvc-exception-handling to learn more about it.

Section 1: Action Filter Lifecycle

In ASP.NET MVC, we have ActionFilter using which we can evaluate incoming requests and process them against these filters e.g. Authentication, Exceptions, Results etc. We can use Exception Filter to monitor any exceptions that occurs during MVC Request processing. In MVC, a request is accepted over the Controller, and then the ActionMethod in the controller is executed. The Exception ActionFilter is applied here. This Action Filter is executed within the scope of Action Method Execution. In the following diagram, the lifecycle of the ActionFilter for handing Exceptions is explained.

exception-filter-lifecycle

The exception filter is applied on the Action Method (alternatively we can even apply it on the Controller containing the Action Method.) The exception filter is executed within the action execution scope. If action method is executed successfully, then the Action Result will be generated where there may be a possibility of exception occurrence e.g. we are using custom view but it is not executed successfully for the current request.

We can implement a custom exception filter as per the needs of the application. Please visit http://devcurry.com/2012/08/custom-action-filter-in-aspnet-mvc-3.html to learn more about it. Furthermore, in Line of Business (LOB) apps, it is important not only to handle exceptions, but to log them in a persistent store (e.g. database) and mail the exception message details to the responsible authority. This makes our MVC application more maintainable.

In this article, we will implement a custom exception and we will use database table to log all exception message details.

Section 2 – Logging Exceptions in an ASP.NET MVC application

We will be implementing this application using Visual Studio 2015. You can use VS 2013 too.

Step 1: Open Visual Studio and create a new ASP.NET Web Application using New Project window. Set the name of the application as MVC_LoggingExcepion_with_ExceptionFilter. Clicking OK on this window will bring up the New ASP.NET Project window. Select Empty MVC project template as shown in the following image

new-mvc-project

Step 2: In the project, add a new Sql Server Database of name ApplicationDB.mdf. Leave this database blank. We will use Entity Framework Code first architecture.

Step 3: In the project in the Models folder, right-click and add a new ADO.NET Entity Data Model of name ApplicationModel. This will start the wizard, in this wizard, in the Choose Model Contents window, select Code First from Database, as shown in the following image

empty-code-first

Click on the Next button and select ApplicationDB.mdf from this window. Click on finish, this will generate ApplicationModel class derived from DbContext class.

Step 4: In the Model folder, add a new class file of name EmployeeInfo.cs with following code in it:

using System.ComponentModel.DataAnnotations;    namespace MVC_LoggingExcepion_with_ExceptionFilter.Models  {      public class EmployeeInfo      {          [Key]          public int EmpNo { get; set; }          public string EmpName { get; set; }          public string Designation { get; set; }          public decimal Salary { get; set; }      }  }  

This is an entity class. We will use this for creating EmployeeInfo table using Code-First with Database approach. In the above class EmpNo is an attribute as Key so that it will be treated as primary key.

Step 5: Since the article describes about logging exception in database, we need a table to store log information. In the Models folder, add a new class file of name ExceptionLogger.cs with the following code in it.

using System;  using System.ComponentModel.DataAnnotations;    namespace MVC_LoggingExcepion_with_ExceptionFilter.Models  {      public class ExceptionLogger      {          [Key]          public int Id { get; set; }          public string ExceptionMessage { get; set; }          public string ControllerName{ get; set; }          public string ExceptionStackTrace { get; set; }          public DateTime LogTime { get; set; }        }  }  

The above class contains properties for storing exception details.

Step 6: In the ApplicationModel.cs class file, add the following properties in the ApplicationModel class (highlighted)

public partial class ApplicationModel : DbContext  {      public ApplicationModel()          : base("name=ApplicationModel")      {                  }        public DbSet<EmployeeInfo> Employees { get; set; }      public DbSet<ExceptionLogger> ExceptionLoggers{ get; set; }      protected override void OnModelCreating(DbModelBuilder modelBuilder)      {      }  }  

These properties will update the database with Employees and ExceptionLoggers table.

 

Step 7: In the project, add a new folder of name CustomFilter. In this folder add a new class of name ExceptionHandlerAttribute with following code.

using MVC_LoggingExcepion_with_ExceptionFilter.Models;  using System;  using System.Web.Mvc;    namespace MVC_LoggingExcepion_with_ExceptionFilter.CustomFilter  {      public class ExceptionHandlerAttribute : FilterAttribute, IExceptionFilter      {          public void OnException(ExceptionContext filterContext)          {              if (!filterContext.ExceptionHandled) {                                       ExceptionLogger logger = new ExceptionLogger()                  {                      ExceptionMessage = filterContext.Exception.Message,                      ExceptionStackTrace = filterContext.Exception.StackTrace,                      ControllerName = filterContext.RouteData.Values["controller"].ToString(),                      LogTime  = DateTime.Now                  };                    ApplicationModel ctx = new ApplicationModel();                  ctx.ExceptionLoggers.Add(logger);                  ctx.SaveChanges();                    filterContext.ExceptionHandled = true;              }          }      }  }  

The above class is derived from the FilterAttribute class, this means that the ExceptionHandlerAttribute class will be used as ActionFilter in the MVC Filter Attribute lifecycle as explained in Section 1. The class implements IExceptionFilter interface and its OnException() method. This method contains logic for storing exception information in ExceptionLoggers table of the database.

Step 8: We need to register the exception filter in our MVC application. To complete the registration, add a new class file of the name FilterConfig in the App_Start folder. In this class, add the following code

using MVC_LoggingExcepion_with_ExceptionFilter.CustomFilter;  using System.Web.Mvc;    namespace MVC_LoggingExcepion_with_ExceptionFilter.App_Start  {      public class FilterConfig      {          public static void RegisterGlobalFilters(GlobalFilterCollection filters)          {              filters.Add(new ExceptionHandlerAttribute());          }      }  }  

Note: Since we have selected an Empty MVC template in Step 1 the above class is not present with us, but if you selected a readymade MVC template then the above class will be already present in the application. This class is used to add all Action Filters in the global configuration. This will be instantiated when the Web application starts.

In Global.asax, add the following line in the Application_Start. (highlighted).

protected void Application_Start()  {      AreaRegistration.RegisterAllAreas();      FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);      RouteConfig.RegisterRoutes(RouteTable.Routes);  }  

Step 8: In the Controllers folder, add a new controller of name EmployeeController with following action methods

using MVC_LoggingExcepion_with_ExceptionFilter.CustomFilter;  using MVC_LoggingExcepion_with_ExceptionFilter.Models;  using System;  using System.Linq;  using System.Web.Mvc;    namespace MVC_LoggingExcepion_with_ExceptionFilter.Controllers  {      public class EmployeeController : Controller      {          ApplicationModel ctx = new ApplicationModel();          // GET: Employee          public ActionResult Index()          {              var Emps = ctx.Employees.ToList();              return View(Emps);          }            public ActionResult Create()          {              return View(new EmployeeInfo());          }            [ExceptionHandler]          [HttpPost]          public ActionResult Create(EmployeeInfo Emp)          {                if (Emp.Designation == "Manager" && (Emp.Salary < 40000 || Emp.Salary > 80000))              {                  throw new Exception("Salary is not Matching with Manager Designatgion");              }              else              if (Emp.Designation == "Operator" && (Emp.Salary < 10000 || Emp.Salary > 20000))              {                  throw new Exception("Salary is not Matching with Operator Designatgion");              }              else {                  ctx.Employees.Add(Emp);                  ctx.SaveChanges();                }                             return View(Emp);          }      }  }  

The Index method returns all Employees. The Create with HttpPost method accepts an Employee object. This method contains some business rules on the Employee Salary based on the Designation. If these rules fail, then an Exception will be thrown. If the Employee Data is correct as per the business rules, then it will be saved in Employee table.

Step 9: Scaffold an Index and Create Views from Index and Create Action methods. In the RouteConfig.cs, modify the route expression as shown in the following code (highlighted)

public static void RegisterRoutes(RouteCollection routes)  {      routes.IgnoreRoute("{resource}.axd/{*pathInfo}");        routes.MapRoute(          name: "Default",          url: "{controller}/{action}/{id}",          defaults: new { controller = "Employee", action = "Index", id = UrlParameter.Optional }      );  }  

The above code will run the Index action method of the EmployeeController which will display Index view.

Step 10: Apply breakpoints on the Create with HttpPost method of the EmployeeController class and the OnException method of the ExceptionHandlerAttribute class. Run the application, the Index View will be displayed. Click on Create New link on this view to display the Create View. Enter data in the Create view as shown in the following image

testdata

We have the Designation as Operator and Salary as 8666, click on the Create button, the control will enter in debug Mode, the if condition for the Operator will throw an exception as shown in the following image

exception-result

Press F5, the control will enter ExceptionHandlerAttribute where the Database logging will take place. Close the application, the database table ExceptionLoggers will show the logged message as shown in the following image

logger-exception

Conclusion:

In a web application, Exception handling and logging is very important. ASP.NET MVC provides this facility using Exception Action Filters. We can create custom action filters to log these exception as per our business need.

Download the entire source code of this article (Github)

View on the web
Inoreader is a light and fast RSS Reader. Follow us on Twitter and Facebook.