Returning Null from a generic method

A friend of mine asked me a question on this today. I hope you find this useful.
Consider this generic method….

 public T Get<T>() {
    //return null
    }

If you want to return null from a C# generic method, which contains the Type T parameter, there are 2 options.

a. Restrict the type parameter T, to be class constraint

 public T Get<T>() where T : class;
   {
      //return null
   }

Value types or Nullable Values types are not allowed. Reference types only.

b. Return default(T) which return null if T is a reference type or a Nullable value type

public T Get<T>()
   {
    return default(T);
   }

Anything else will simply return their default values. Here is a summary on both reference and value types….

//If T is a reference type

var retVal = f.Get<String>(); //return null

//If T is a value type - int
var retValInt = f.Get<int>(); //return 0

//If T is a value type - char
var retValChar = f.Get<char>(); //return '\0'

//If T is a value type - bool
var retValBool = f.Get<Boolean>(); //return false

//If T is a value type - enum
var retValEnum = f.Get<EnumType>(); // For enum types, if there are no enum values specified, then the return value is 0. If there are values, then the first enumeration returns as the default.

//If T is a value type - struct
var retValStruct = f.Get<Bar>(); //Structs, returns the value of the struct

//If T is a Nullable<Int32>
var retNullableInt = f.Get<Int32?>(); //return null

Returning Null from a generic method

 

Consider this generic method.

   1: public T Get<T>() { 

   2: //return null

   3: }

   4:  

If you want to return null from a C# generic method, which contains the Type(T) parameter, there are 2 options.

a. Restrict the type parameter T, to be class constraint

   1: public T Get<T>() where T : class;

   2: {

   3:    //return null

   4: }

   5:  

Value types or Nullable Values types are not allowed. Reference types only.

b. Return default(T) which return null if T is a reference type or a Nullable value type

   1: public T Get<T>()

   2: {

   3:   return default(T);

   4: }

   5:  

Anything else will simply return their default values.  Here is summary on both reference and value types….

//If T is a reference type

var retVal = f.Get<String>(); //return null

……….

//If T is a value type – int

var retValInt = f.Get<int>(); //return 0

……….

//If T is a value type – char

var retValChar = f.Get<char>(); //return ”

……….

//If T is a value type – bool

var retValBool = f.Get<Boolean>(); //return false

……….

//If T is a value type – enum

var retValEnum = f.Get<EnumType>(); // For enum types, if there are no enum values specified, then the return value is 0. If there are values, then the first enumeration returns as the default.

……….

//If T is a value type – struct

var retValStruct = f.Get<Bar>(); //Structs, returns the value of the struct

……….

//If T is a Nullable<Int32>

var retNullableInt = f.Get<Int32?>(); //return null

……….

Moq 4 and “LINQ to Mocks”

While searching for Moq code samples, I came across that Moq 4 was released few months ago. The key improvement was the new “LINQ to Mocks”.

This post demonstrates few examples of the usage of Mocks and LINQ queries. For each example, we stub out dependencies using lambda expressions first, and then see the corresponding LINQ version. At the end we see the performance of each Unit Tests.

Note: I’m using the xUnit Testing Framework. However you can apply the same principles to other Unit testing frameworks.

Single Stub

Lambdas:

   1: [Fact]

   2: public void UpdateCustomer_WhenCustomerIsNotUpdated_ReturnsFalse()

   3: {

   4:     //Arrange

   5:     var dbServiceStub = new Mock<IDbService>();

   6:     dbServiceStub.Setup(d => d.Update(It.IsAny<Customer>())).Returns(false);

   7:     var customerService = new CustomerService();

   8:     customerService.DbService = dbServiceStub.Object;

   9:

  10:     //Act

  11:     bool isUpdated = customerService.Update(It.IsAny<Customer>());

  12:

  13:     //Assert

  14:     Assert.False(isUpdated);

  15: }

LINQ:

   1: [Fact]

   2:  public void UpdateCustomer_WhenCustomerIsNotUpdated_ReturnsFalse()

   3:  {

   4:      //Arrange

   5:      IDbService dbServiceStub = (from dbService in Mocks.Of<IDbService>() where dbService.Update(It.IsAny<Customer>()) == false

   6:                                  select dbService).First();

   7:      var customerService = new CustomerService { DbService = dbServiceStub };

   8:

   9:      //Act

  10:      bool isUpdated = customerService.Update(It.IsAny<Customer>());

  11:

  12:      //Assert

  13:      Assert.False(isUpdated);

  14:  }

 

Multiple Stubs

Lambdas:

   1: [Fact]

   2: public void UpdateCustomer_WhenCustomerIsUpdated_ReturnsTrue()

   3: {

   4:     //Arrange

   5:     var dbServiceStub = new Mock<IDbService>();

   6:     dbServiceStub.Setup(d => d.Update(It.IsAny<Customer>())).Returns(true);

   7:     var loggerServiceStub = new Mock<ILoggerService>();

   8:

   9:     var customerService = new CustomerService { DbService = dbServiceStub.Object, LogService = loggerServiceStub.Object };

  10:

  11:     //Act

  12:     bool isUpdated = customerService.Update(It.IsAny<Customer>());

  13:

  14:     //Assert

  15:     Assert.True(isUpdated);

  16: }

 

LINQ:

   1: [Fact]

   2: public void UpdateCustomer_WhenCustomerIsUpdated_ReturnsTrue()

   3: {

   4:     //Arrange

   5:     var fakes = (from dbService in Mocks.Of<IDbService>()

   6:                  from loggerService in Mocks.Of<ILoggerService>()

   7:                  where dbService.Update(It.IsAny<Customer>()) == true

   8:                  select new { dbServiceStub = dbService, loggerServiceStub = loggerService }).First();

   9:

  10:     var customerService = new CustomerService { DbService = fakes.dbServiceStub, LogService = fakes.loggerServiceStub };

  11:

  12:     //Act

  13:     bool isUpdated = customerService.Update(It.IsAny<Customer>());

  14:

  15:     //Assert

  16:     Assert.True(isUpdated);

  17: }

Mocks and Stubs

 

Lambdas:

   1: [Fact]

   2: public void UpdateCustomer_WhenCustomerIsUpdated_VerifyLoggerServiceLogIsCalled()

   3: {

   4:     //Arrange

   5:     var dbServiceStub = new Mock<IDbService>();

   6:     dbServiceStub.Setup(d => d.Update(It.IsAny<Customer>())).Returns(true);

   7:     var loggerServiceMock = new Mock<ILoggerService>(); //We verify against the Mock

   8:     loggerServiceMock.Setup(l => l.Log(It.IsAny<string>())).Verifiable();

   9:

  10:     var customerService = new CustomerService()

  11:     {

  12:         DbService = dbServiceStub.Object,

  13:         LogService = loggerServiceMock.Object

  14:     };

  15:

  16:     //Act

  17:     customerService.Update(It.IsAny<Customer>());

  18:

  19:     //Assert

  20:     Mock.Get(loggerServiceMock.Object).Verify(c => c.Log(It.IsAny<string>()));

  21: }

LINQ:

   1: [Fact]

   2: public void UpdateCustomer_WhenCustomerIsUpdated_VerifyLoggerServiceLogIsCalled()

   3: {

   4:     //Arrange

   5:     var fakes = (from dbService in Mocks.Of<IDbService>()

   6:                  from loggerService in Mocks.Of<ILoggerService>()

   7:                  where dbService.Update(It.IsAny<Customer>()) == true

   8:                  select new { dbServiceStub = dbService, loggerServiceMock = loggerService }).First();

   9:

  10:     var customerService = new CustomerService { DbService = fakes.dbServiceStub, LogService = fakes.loggerServiceMock };

  11:

  12:     //Act

  13:     bool isSend = customerService.Update(It.IsAny<Customer>());

  14:

  15:     //Assert

  16:     Mock.Get(fakes.loggerServiceMock).Verify(c => c.Log(It.IsAny<string>()));

  17: }

 

Testing an MVC Action Filter

Lambdas:

   1: [Fact]

   2: public void OnActionExecuted_WhenEmployeeSalaryIsEqualToZero_ EnsureActionExecutedContextResultEqualToFilterResult()

   3: {

   4:     //Arrange

   5:     decimal employeeUnpaidAmount = 0.0M;

   6:     var employeeServiceStub = new Mock<IEmployeeService>();

   7:     employeeServiceStub.Setup(s => s.GetSalary()).Returns(employeeUnpaidAmount);

   8:

   9:     var filter = new EmployeeSalaryNotificationAttribute

  10:     {

  11:         EmployeeService = employeeServiceStub.Object

  12:     };

  13:

  14:     var actionExecutedContextMock = new Mock<ActionExecutedContext>();

  15:     var routeData = new RouteData();

  16:     routeData.Values.Add("fakeIdKey", "fakeIdValue");

  17:     actionExecutedContextMock.SetupGet(r => r.RouteData).Returns(routeData);

  18:

  19:     var request = new Mock<HttpRequestBase>();

  20:     var httpContext = new Mock<HttpContextBase>();

  21:     httpContext.SetupGet(c => c.Request).Returns(request.Object);

  22:     actionExecutedContextMock.SetupGet(h => h.HttpContext).Returns(httpContext.Object);

  23:

  24:     //Act

  25:     filter.OnActionExecuted(actionExecutedContextMock.Object);

  26:

  27:     //Assert

  28:     Assert.Equal((actionExecutedContextMock.Object.Result as ContentResult).Content, filter.SalaryResult);

  29: }

LINQ:

   1: [Fact]

   2: public void OnActionExecuted_WhenEmployeeSalaryIsEqualToZero_EnsureActionExecutedContextResultEqualToFilterResult()

   3: {

   4:     //Arrange

   5:     RouteData routeData = new RouteData();

   6:     routeData.Values.Add("fakeIdKey", "fakeIdValue");

   7:

   8:     var fakes = (from employeeService in Mocks.Of<IEmployeeService>()

   9:                  from actionExecutedContext in Mocks.Of<ActionExecutedContext>()

  10:                  where employeeService.GetSalary() == 0.00M &&

  11:                  actionExecutedContext.HttpContext == Mock.Of<HttpContextBase>() &&

  12:                  actionExecutedContext.HttpContext.Request == Mock.Of<HttpRequestBase>() &&

  13:                  actionExecutedContext.RouteData == new RouteData()

  14:                  select new { EmployeeServiceStub = employeeService, ActionExecutedContextMock = actionExecutedContext })

  15:                  .First();

  16:

  17:     var filter = new EmployeeSalaryNotificationAttribute

  18:     {

  19:         EmployeeService = fakes.EmployeeServiceStub

  20:     };

  21:

  22:     //Act

  23:     filter.OnActionExecuted(fakes.ActionExecutedContextMock);

  24:

  25:     //Assert

  26:     Assert.Equal((fakes.ActionExecutedContextMock.Result as ContentResult).Content, filter.SalaryResult);

  27: }

 

Key things to notice:

– The tests with LINQ queries reflect the test scenarios/conditions in a more of a specification style. This improves the tests readability.

– The query returns an infinite number of mocks. Typically we access the first element.

var fakes = (LINQ query).First();

– LINQ query result returns real object(s) and not the type Mock<T>. So we do not need to use the EmployeeServiceStub.Object. Instead we can just use the returned element.

EmployeeService = fakes.EmployeeServiceStub;

 

– When you have multiple stubs or mocks, you can return all of them using an anonymous type.

   select new { dbServiceStub = dbService, loggerServiceStub = loggerService }));

– Not used in these code samples, but if you are using the MockFactory class, it is now absolute in v4. MockFactory will be retired in v5.

 

Performances:

Here is a very quick benchmark results on each Unit Test.

Test

Lambda

LINQ

UpdateCustomer_WhenCustomerIsNotUpdated

_ReturnsFalse

0.95s

1.01s

UpdateCustomer_WhenCustomerIsUpdated

_ReturnsTrue

 

0.97s

 

1.06s

 

UpdateCustomer_WhenCustomerIsUpdated

_VerifyLoggerServiceLogIsCalled

 

0.94s

 

1.07s

 

 

OnActionExecuted_WhenEmployeeSalaryIsEqualToZero

_EnsureFilterResultContainsTheStringNotPaid

 

1.08s

 

1.29s

 

 

Unit Tests with LINQ queries take “tiny” bit longer than the Lambda counterparts. However, I would personally still use LINQ version as it improves the readability of Unit Tests.

Moq 4 and “LINQ to Mocks”

“If the code samples are harder to follow please visit my blog https://blog.rajsoftware.com/post/2011/06/07/Moq-4-and-e2809cLINQ-to-Mockse2809d.aspx

While searching for Moq code samples, I came across that Moq 4 was released few months ago. The key improvement was the new “LINQ to Mocks”.

This post demonstrates few examples of the usage of Mocks and LINQ queries. For each example, we stub out dependencies using lambda expressions first, and then see the corresponding LINQ version. At the end we see the performance of each Unit Tests.

Note: I’m using the xUnit Testing Framework. However you can apply the same principles to other Unit testing frameworks.

 

Single Stub

Lambdas:

 1: [Fact]

 

 2: public void UpdateCustomer_WhenCustomerIsNotUpdated_ReturnsFalse()

 

 3: {

 

 4:     //Arrange

 

 5:     var dbServiceStub = new Mock<IDbService>();

 

 6:     dbServiceStub.Setup(d => d.Update(It.IsAny<Customer>())).Returns(false);

 

 7:     var customerService = new CustomerService();

 

 8:     customerService.DbService = dbServiceStub.Object;

 

 9:

 

 10:     //Act

 

 11:     bool isUpdated = customerService.Update(It.IsAny<Customer>());

 

 12:

 

 13:     //Assert

 

 14:     Assert.False(isUpdated);

 

 15: }

 

LINQ:

 1: [Fact]

 

 2:  public void UpdateCustomer_WhenCustomerIsNotUpdated_ReturnsFalse()

 

 3:  {

 

 4:      //Arrange

 

 5:      IDbService dbServiceStub = (from dbService in Mocks.Of<IDbService>() where dbService.Update(It.IsAny<Customer>()) == false

 

 6:                                  select dbService).First();

 

 7:      var customerService = new CustomerService { DbService = dbServiceStub };

 

 8:

 

 9:      //Act

 

 10:      bool isUpdated = customerService.Update(It.IsAny<Customer>());

 

 11:

 

 12:      //Assert

 

 13:      Assert.False(isUpdated);

 

 14:  }

 

 

Multiple Stubs

Lambdas:

 1: [Fact]

 

 2: public void UpdateCustomer_WhenCustomerIsUpdated_ReturnsTrue()

 

 3: {

 

 4:     //Arrange

 

 5:     var dbServiceStub = new Mock<IDbService>();

 

 6:     dbServiceStub.Setup(d => d.Update(It.IsAny<Customer>())).Returns(true);

 

 7:     var loggerServiceStub = new Mock<ILoggerService>();

 

 8:

 

 9:     var customerService = new CustomerService { DbService = dbServiceStub.Object, LogService = loggerServiceStub.Object };

 

 10:

 

 11:     //Act

 

 12:     bool isUpdated = customerService.Update(It.IsAny<Customer>());

 

 13:

 

 14:     //Assert

 

 15:     Assert.True(isUpdated);

 

 16: }

 

 

LINQ:

 1: [Fact]

 

 2: public void UpdateCustomer_WhenCustomerIsUpdated_ReturnsTrue()

 

 3: {

 

 4:     //Arrange

 

 5:     var fakes = (from dbService in Mocks.Of<IDbService>()

 

 6:                  from loggerService in Mocks.Of<ILoggerService>()

 

 7:                  where dbService.Update(It.IsAny<Customer>()) == true

 

 8:                  select new { dbServiceStub = dbService, loggerServiceStub = loggerService }).First();

 

 9:

 

 10:     var customerService = new CustomerService { DbService = fakes.dbServiceStub, LogService = fakes.loggerServiceStub };

 

 11:

 

 12:     //Act

 

 13:     bool isUpdated = customerService.Update(It.IsAny<Customer>());

 

 14:

 

 15:     //Assert

 

 16:     Assert.True(isUpdated);

 

 17: }

 

 

 

Mocks and Stubs

 

Lambdas:

 1: [Fact]

 

 2: public void UpdateCustomer_WhenCustomerIsUpdated_VerifyLoggerServiceLogIsCalled()

 

 3: {

 

 4:     //Arrange

 

 5:     var dbServiceStub = new Mock<IDbService>();

 

 6:     dbServiceStub.Setup(d => d.Update(It.IsAny<Customer>())).Returns(true);

 

 7:     var loggerServiceMock = new Mock<ILoggerService>(); //We verify against the Mock

 

 8:     loggerServiceMock.Setup(l => l.Log(It.IsAny<string>())).Verifiable();

 

 9:

 

 10:     var customerService = new CustomerService()

 

 11:     {

 

 12:         DbService = dbServiceStub.Object,

 

 13:         LogService = loggerServiceMock.Object

 

 14:     };

 

 15:

 

 16:     //Act

 

 17:     customerService.Update(It.IsAny<Customer>());

 

 18:

 

 19:     //Assert

 

 20:     Mock.Get(loggerServiceMock.Object).Verify(c => c.Log(It.IsAny<string>()));

 

 21: }

 

 

LINQ:

 1: [Fact]

 

 2: public void UpdateCustomer_WhenCustomerIsUpdated_VerifyLoggerServiceLogIsCalled()

 

 3: {

 

 4:     //Arrange

 

 5:     var fakes = (from dbService in Mocks.Of<IDbService>()

 

 6:                  from loggerService in Mocks.Of<ILoggerService>()

 

 7:                  where dbService.Update(It.IsAny<Customer>()) == true

 

 8:                  select new { dbServiceStub = dbService, loggerServiceMock = loggerService }).First();

 

 9:

 

 10:     var customerService = new CustomerService { DbService = fakes.dbServiceStub, LogService = fakes.loggerServiceMock };

 

 11:

 

 12:     //Act

 

 13:     bool isSend = customerService.Update(It.IsAny<Customer>());

 

 14:

 

 15:     //Assert

 

 16:     Mock.Get(fakes.loggerServiceMock).Verify(c => c.Log(It.IsAny<string>()));

 

 17: }

 

 

Testing an MVC Action Filter

 

Lambdas:

 1: [Fact]

 

 2: public void OnActionExecuted_WhenEmployeeSalaryIsEqualToZero_ EnsureActionExecutedContextResultEqualToFilterResult()

 

 3: {

 

 4:     //Arrange

 

 5:     decimal employeeUnpaidAmount = 0.0M;

 

 6:     var employeeServiceStub = new Mock<IEmployeeService>();

 

 7:     employeeServiceStub.Setup(s => s.GetSalary()).Returns(employeeUnpaidAmount);

 

 8:

 

 9:     var filter = new EmployeeSalaryNotificationAttribute

 

 10:     {

 

 11:         EmployeeService = employeeServiceStub.Object

 

 12:     };

 

 13:

 

 14:     var actionExecutedContextMock = new Mock<ActionExecutedContext>();

 

 15:     var routeData = new RouteData();

 

 16:     routeData.Values.Add("fakeIdKey", "fakeIdValue");

 

 17:     actionExecutedContextMock.SetupGet(r => r.RouteData).Returns(routeData);

 

 18:

 

 19:     var request = new Mock<HttpRequestBase>();

 

 20:     var httpContext = new Mock<HttpContextBase>();

 

 21:     httpContext.SetupGet(c => c.Request).Returns(request.Object);

 

 22:     actionExecutedContextMock.SetupGet(h => h.HttpContext).Returns(httpContext.Object);

 

 23:

 

 24:     //Act

 

 25:     filter.OnActionExecuted(actionExecutedContextMock.Object);

 

 26:

 

 27:     //Assert

 

 28:     Assert.Equal((actionExecutedContextMock.Object.Result as ContentResult).Content, filter.SalaryResult);

 

 29: }

 

 

LINQ:

 1: [Fact]

 

 2: public void OnActionExecuted_WhenEmployeeSalaryIsEqualToZero_EnsureActionExecutedContextResultEqualToFilterResult()

 

 3: {

 

 4:     //Arrange

 

 5:     RouteData routeData = new RouteData();

 

 6:     routeData.Values.Add("fakeIdKey", "fakeIdValue");

 

 7:

 

 8:     var fakes = (from employeeService in Mocks.Of<IEmployeeService>()

 

 9:                  from actionExecutedContext in Mocks.Of<ActionExecutedContext>()

 

 10:                  where employeeService.GetSalary() == 0.00M &&

 

 11:                  actionExecutedContext.HttpContext == Mock.Of<HttpContextBase>() &&

 

 12:                  actionExecutedContext.HttpContext.Request == Mock.Of<HttpRequestBase>() &&

 

 13:                  actionExecutedContext.RouteData == new RouteData()

 

 14:                  select new { EmployeeServiceStub = employeeService, ActionExecutedContextMock = actionExecutedContext })

 

 15:                  .First();

 

 16:

 

 17:     var filter = new EmployeeSalaryNotificationAttribute

 

 18:     {

 

 19:         EmployeeService = fakes.EmployeeServiceStub

 

 20:     };

 

 21:

 

 22:     //Act

 

 23:     filter.OnActionExecuted(fakes.ActionExecutedContextMock);

 

 24:

 

 25:     //Assert

 

 26:     Assert.Equal((fakes.ActionExecutedContextMock.Result as ContentResult).Content, filter.SalaryResult);

 

 27: }

 

 

Key things to notice:

– The tests with LINQ queries reflect the test scenarios/conditions in a more of a specification style. This improves the tests readability.

 

– The query returns an infinite number of mocks. Typically we access the first element.

   var fakes = (LINQ query).First();

 

– LINQ query result returns real object(s) and not the type Mock<T>. So we do not need to use the EmployeeServiceStub.Object. Instead we can just use the returned element.

   EmployeeService = fakes.EmployeeServiceStub;

 

– When you have multiple stubs or mocks, you can return all of them using an anonymous type.

   select new { dbServiceStub = dbService, loggerServiceStub = loggerService }));

 

– Not used in these code samples, but if you are using the MockFactory class, it is now absolute in v4. MockFactory will be retired in v5.

 

Performances:

Here is a very quick benchmark results on each Unit Test.

Unit Test Lambda version LINQ version
UpdateCustomer_WhenCustomerIsNotUpdated_ReturnsFalse 0.95s 1.01s
UpdateCustomer_WhenCustomerIsUpdated_ReturnsTrue 0.97s 1.06s
UpdateCustomer_WhenCustomerIsUpdated

_VerifyLoggerServiceLogIsCalled

0.94s 1.07s
OnActionExecuted_WhenEmployeeSalaryIsEqualToZero

_EnsureFilterResultContainsTheStringNotPaid

1.08s 1.29s

 

Unit Tests with LINQ queries take “tiny” bit longer than the Lambda counterparts. However, I would personally still use LINQ version as it improves the readability of Unit Tests.

ASP.NET MVC 3 Model Metadata Providers

One of the cool features of ASP.NET MVC framework is the ability provide Model’s metadata using DataAnnotation attributes. Below is a comprehensive example on how Model Metadata Providers behave using the new ASP.NET MVC 3 Display DataAnnotation attribute as an example.

Please refer to my post below.

http://www.dotnetcurry.com/ShowArticle.aspx?ID=715

16/6/2011 – Nice to see this post hit the front page of http://asp.net/mvc

MVC 3 Filter Ordering

MVC 3 has introduced couple of new approaches related to the run order of filters. In this article, we will look at the order of filters execution.

image

There are different types of filters in MVC. Depending on the type of the Filter, and the scope of the Filter, the order of the execution also changes.

You may already aware that there are different types of filters within MVC framework. They are listed below.

1. Authorization filters

2. Action filters

3. Response/Result filters

4. Exception filters

The above list is ordered as exactly the order they executes within MVC framework. The Authorization filters always run first, and the Exception filters run at the end.

Specifying the Order property for Filters

Within each filter, you may specify the Order property. (All filters are derived from the abstract class FilterAttribute, and this class has an Order property). This property will ensure the filter runs in a specific Order. For an example, let’s say we have 2 Authorization filters, AuthorizationFilterA and AuthorizationFilterB and they are implemented as below.

public class AuthorizationFilterA : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
         Debug.WriteLine("OnAuthorization : AuthorizationFilterA");   
     }
}


public class AuthorizationFilterB : AuthorizeAttribute
{
     public override void OnAuthorization(AuthorizationContext filterContext)
     {
         Debug.WriteLine("OnAuthorization : AuthorizationFilterB");
     }
}

Now, if I want these two filters to run in a specific order – AuthorizationFilterB to run first, and AuthorizationFilterA to run second, I can simply specify the execution order as below.

[AuthorizationFilterA(Order=2)]
[AuthorizationFilterB(Order=1)]
public ActionResult Index()
{          
    return View();
}

When you run the code, the Output window should display that AuthorizationFilterB runs first, AuthorizationFilterA runs second.

OnAuthorization : AuthorizationFilterB

OnAuthorization : AuthorizationFilterA

Filter Scope

Within each filter type, you can define a scope. For an example, I could scope all my Authorization Filters to run within the Controller Scope, and all Action Filters to run in Global scope (Every Action within the MVC application).

FilterScope.Global is a new scope which was introduced in MVC 3. The existing scopes are First, Controller, Action, and Last. The complete enumeration is defined as below.

namespace System.Web.Mvc {
  public enum FilterScope {
       First = 0,
       Global = 10,
       Controller = 20,
        Action = 30,
        Last = 100,
   }
 }
 

By default, the filters with the lowest scope runs first. For an example, scope Global (10) executes first and scope Controller (20) executes second.

Filter Scope with explicit Ordering

Below example shows, how explicit filter ordering (using Order property) and scope of the filters determine their correct run order.

Let’s add the scope to our existing Authorization Filters – AuthorisationFilterA and AuthorisationFilterB. Please note that we haven’t changed the usage of Order property.

AuthorizationFilterA(Order 2) has the scope Global.

AuthorizationFilterB(Order 1) has the scope Action.

 public class AuthorizationFilterA : AuthorizeAttribute
 {
      public override void OnAuthorization(AuthorizationContext filterContext)
      {
          Debug.WriteLine("OnAuthorization : AuthorizationFilterA (Order: 2) in scope : Global");   
      }
  }

public class AuthorizationFilterB : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        Debug.WriteLine("OnAuthorization : AuthorizationFilterB (Order: 1) in scope : Action");   
    }
}

[AuthorizationFilterB(Order = 1)]
public ActionResult Index()
{           
    return View();
}
   
GobalFilters.Filters.Add(new AuthorizationFilterA() { Order = 2});

According to the above Filter Scope enumeration, if we were to specify only the scope but not the Order property, then we would expect AuthorizationFilterA (in Global scope) to run first, and AuthorizationFilterB (in Action scope) to run second. Since we are explicitly specifying the Order property for both filters, AuthorizationFilterB (in Action scope – Order 1) runs first and AuthorizationFilterA (in Global scope – Order 2) runs second.

Output:

OnAuthorization : AuthorizationFilterB (Order: 1) in scope : Action

OnAuthorization : AuthorizationFilterA (Order: 2) in scope : Global

Now let’s add another Authorization filter (AuthorizationFilterC) to Global scope. Also note that we have not specified the Order property.

  
public class AuthorizationFilterC : AuthorizeAttribute
{
      public override void OnAuthorization(AuthorizationContext filterContext)
      {
          Debug.WriteLine("OnAuthorization : AuthorizationFilterC (no Order defined) in scope : Global");
      }
 
    
GlobalFilters.Filters.Add(new AuthorizationFilterC());
   

After running all three filters, you can see the output as below.

Output

OnAuthorization : AuthorizationFilterC (no Order defined) in scope : Global

OnAuthorization : AuthorizationFilterB (Order: 1) in scope : Action

OnAuthorization : AuthorizationFilterA (Order: 2) in scope : Global

For same Filter type, the filters without the explicit ordering (i.e AuthorizationFilterC) take precedence over the filters with explicit ordering (AuthorizationFilterB, AuthorizationFilterA).

Now let’s remove the Order property from both AuthorizationFilterB and AuthorizationFilterA

  
[AuthorizationFilterB]
 public ActionResult Index()
 { 
     return View();
 }
  
 GlobalFilters.Filters.Add(new AuthorizationFilterA());

Output:

OnAuthorization : AuthorizationFilterA (no order defined) in scope : Global

OnAuthorization : AuthorizationFilterC (no order defined) in scope : Global

OnAuthorization : AuthorizationFilterB (no order defined) in scope : Action

As we would expect, the filters with scope Global (AuthorizationFilterA and AuthorizationFilterC) run first and second in order, the scope Action filter (AuthorizationFilterC) runs at the end. 2 Global filters (AuthorizationFilterA and AuthorizationFilterC) run order relies on the order which they were added to the Global Filter collection. In this example AuthorizationFilterA which was added prior to AuthorizationFilterC ,runs first.

For the same filters, when determine the run order, first it sorts them by their order (lowest numbers first), and then by their scope (also lowest numbers first).

Controller as a Filter

In MVC the Controller itself is also a Filter. Controller implements all filters, so Controller can subscribe to all filter events.

  
public abstract class Controller : ControllerBase, 
IActionFilter, IAuthorizationFilter, IDisposable, 
IExceptionFilter, IResultFilter

MVC framework ensures, the Controller always runs first, before any other filters get executed. It has been accomplished by specifying the scope as the First and the order property as Int32.MinValue. By default, an MVC filter has the value for the Order -1. Therefore Int32.MinValue along with the Scope First together ensures the Controller always runs first.

  
public class ControllerInstanceFilterProvider : IFilterProvider {
        public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
            if (controllerContext.Controller != null) {
                // Use FilterScope.First and Order of Int32.MinValue to ensure controller instance methods always run first
                yield return new Filter(controllerContext.Controller, FilterScope.First, Int32.MinValue);
            }
        }
    }

Forward Filter Order and Reverse Filter Order

So far we have discussed the order of filters which get executed based on the explicit ordering (using Order property) and the scope which they can be belong to. However, MVC filters run order, do not only rely only by these two factors. Sometimes filters run in forward order and sometimes filters run in reverse order. Let’s see the below example.

Let’s say I have three Action filters (ActionFilter1, ActionFilter2, ActionFilter3), one Authorization filter (AuthorizationFilter) and two Exception filters (HandleErrorA, HandleErrorB). They are implemented as below.

 
public class ActionFilter1 : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Debug.WriteLine("Forward Order - OnActionExecuting : ActionFilter1 (Scope Global)");
    }
 
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Debug.WriteLine("Reverse Order - OnActionExecuted : ActionFilter1 (Scope Global)");
    }
 
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        Debug.WriteLine("Forward Order - OnResultExecuting : ActionFilter1 (Scope Global)");
    }
 
    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        Debug.WriteLine("Reverse Order - OnResultExecuted : ActionFilter1 (Scope Global)");
    }
}

 
public class ActionFilter2 : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
     {
         Debug.WriteLine("Forward Order - OnActionExecuting : ActionFilter2 (Scope Controller)");
     }
  
     public override void OnActionExecuted(ActionExecutedContext filterContext)
     {
         Debug.WriteLine("Reverse Order - OnActionExecuted : ActionFilter2 (Scope Controller)");
     }
  
     public override void OnResultExecuting(ResultExecutingContext filterContext)
     {
         Debug.WriteLine("Forward Order - OnResultExecuting : ActionFilter2 (Scope Controller)");
     }
  
     public override void OnResultExecuted(ResultExecutedContext filterContext)
     {
         Debug.WriteLine("Reverse Order - OnResultExecuted : ActionFilter2 (Scope Controller)");
     }
 }
  
 public class ActionFilter3 : ActionFilterAttribute
 {
     public override void OnActionExecuting(ActionExecutingContext filterContext)
     {
         Debug.WriteLine("Forward Order - OnActionExecuting : ActionFilter3 (Scope Action)");
     }
  
     public override void OnActionExecuted(ActionExecutedContext filterContext)
     {
         Debug.WriteLine("Reverse Order - OnActionExecuted : ActionFilter3 (Scope Action)");
     }
  
     public override void OnResultExecuting(ResultExecutingContext filterContext)
     {
         Debug.WriteLine("Forward Order - OnResultExecuting : ActionFilter3 (Scope Action)");
     }
  
     public override void OnResultExecuted(ResultExecutedContext filterContext)
     {
         Debug.WriteLine("Reverse Order - OnResultExecuted : ActionFilter3 (Scope Action)");
     }
 }
  
  
 public class AuthorizationFilter : AuthorizeAttribute
 {
     public override void OnAuthorization(AuthorizationContext filterContext)
     {
         Debug.WriteLine("Forward Order - OnAuthorization : AuthorizationFilter (Scope Controller)");
     }
 }
  
  
 public class HandleErrorA : HandleErrorAttribute
 {
     public override void OnException(ExceptionContext filterContext)
     {
         Debug.WriteLine("Reverse Order - OnException : HandleErrorA (Scope Action)");
     }
 }
  
 public class HandleErrorB : HandleErrorAttribute
 {
     public override void OnException(ExceptionContext filterContext)
     {
         Debug.WriteLine("Reverse Order - OnException : HandleErrorB (Scope Action)");
     }
 }
 

We will register the above filters as below…

ActionFilter1 has the scope Global, ActionFIlter2 has the scope Controller, ActionFIlter3 has the Scope Action, AuthorizationFilter has the scope Controller, HandleErrorA has the scope Global, and HandleErrorB has the scope Action.

At the beginning of this article I mentioned that the run order of different types of filters. First Authorization filters, then Action Filters, followed by Result filters and at the end the Exception filters. This is true, however within each type of filters, some executes in reverse order and some executes in forward order.

The best way to explain is to examine the generated output.

Forward Order – OnAuthorization : AuthorizationFilter (Scope Controller)

Forward Order – OnActionExecuting : ActionFilter1 (Scope Global)

Forward Order – OnActionExecuting : ActionFilter2 (Scope Controller)

Forward Order – OnActionExecuting : ActionFilter3 (Scope Action)

Home Controller, Index Action

Reverse Order – OnActionExecuted : ActionFilter3 (Scope Action)

Reverse Order – OnActionExecuted : ActionFilter2 (Scope Controller)

Reverse Order – OnActionExecuted : ActionFilter1 (Scope Global)

Forward Order – OnResultExecuting : ActionFilter1 (Scope Global)

Forward Order – OnResultExecuting : ActionFilter2 (Scope Controller)

Forward Order – OnResultExecuting : ActionFilter3 (Scope Action)

Reverse Order – OnResultExecuted : ActionFilter3 (Scope Action)

Reverse Order – OnResultExecuted : ActionFilter2 (Scope Controller)

Reverse Order – OnResultExecuted : ActionFilter1 (Scope Global)

Reverse Order – OnException : HandleErrorB (Scope Action)

Reverse Order – OnException : HandleErrorA (Scope Global)

  • There is only one Authorization Filter in Controller scope and it runs first as expected.
  • The Action Filters run at second. Notice that OnActionExecuting event runs in an order where the order of filter execution is determined by their scope (lowest number first in the enumeration). As you see, Action Filters OnActionExecuting event runs in a forward order.
  • Home Controller’s Index Action executes.
  • Action Filters do not always run in forward order. As you see during OnActionExecuted event, they run in a reverse order.
  • Very similar to OnActionExecuted event, OnResultExecuted event runs in reverse order.
  • Error Handler filters run at last. For each Error Handler filter, OnException event runs in  reverse order. Prior to MVC 3, ErrorHandler’s OnException event ran in forward order. This approach makes MVC exception filters more aligned with .NET exception handlers.

Summary

There are multiple factors involved when deciding the run order of MVC filters. This includes the explicit ordering, the scope they belong to, and the type of the filter. Controller itself is a filter and always run first. By design, MVC executes certain filters in specific order. Some are run in forward order and some are run in reverse order.

For your favourite posts, subscribe to my blog: http://blog.rajsoftware.com

https://blog.rajsoftware.com/post/2011/05/14/MVC3-Filter-Ordering.aspx

A tip on type Inference in Generic Methods

As you may already know C# support type interfaces for generic methods. I have seen many developers write code like below for both extension methods and generic methods.

public static bool IsGreaterThan<T>(T x, T y) where T : IComparable<T>
{
      if (x.CompareTo(y) > 0)
      {
          return true;
      }

      return false;
 }

Extension method:

public static bool IsGreaterThanExt<T>(this T x, T y) where T : IComparable<T>
           {
               if (x.CompareTo(y) > 0)
               {
                   return true;
               }

               return false;
           }

The Usage:

Console.WriteLine(IsGreaterThan<int>(4, 3));
Console.WriteLine(4.IsGreaterThanExt<int>(3));

The above is redundant. The reason is that the type is automatically inferred by the C# compiler.
Now you can simply call the methods without the type

Console.WriteLine(IsGreaterThan(4, 3));
Console.WriteLine(4.IsGreaterThanExt(3))