Skip to content

Instantly share code, notes, and snippets.

@ivanrad
Created February 15, 2014 13:23
Show Gist options
  • Select an option

  • Save ivanrad/9019273 to your computer and use it in GitHub Desktop.

Select an option

Save ivanrad/9019273 to your computer and use it in GitHub Desktop.
Disable FilterAttribute Instance Caching in ASP.NET MVC 3/4 (by replacing the default instance of FilterAttributeFilterProvider with a non-caching one)

One of the breaking changes in ASP.NET MVC 3 (and upwards) is that action filters, once instantiated, are cached and re-used on subsequent requests. Here is the relevant excerpt from the official ASP.NET MVC 3 release notes:

In previous versions of ASP.NET MVC, action filters are create per request except in a few cases. This behavior was never a guaranteed behavior but merely an implementation detail and the contract for filters was to consider them stateless. In ASP.NET MVC 3, filters are cached more aggressively. Therefore, any custom action filters which improperly store instance state might be broken.

Essentially, if you are dealing with legacy code, that has poorly implemented custom action filters, you may end up with unexpected behavior once you migrate to a newer ASP.NET MVC release.

So, what is one to do?

Well, apparently, the default filter provider (FilterAttributeFilterProvider) can be coerced into not caching instances of action filters. As it happens, its constructor has a very convenient boolean argument that can be used to control whether caching is enabled or disabled. All that is needed is to replace the default instance of FilterAttributeFilterProvider, registered with FilterProviders, with a non-caching instance in Global.asax.cs:

  public class Global : System.Web.HttpApplication
  {
    protected void Application_Start(object sender, EventArgs e)
    {
      // ...
      // replace the default instance of FilterAttributeFilterProvider, registered with FilterProviders, with a non-caching one
      var defaultFilterAttrProvider = 
        FilterProviders.Providers.SingleOrDefault(
        provider => provider is FilterAttributeFilterProvider);
      if (defaultFilterAttrProvider != null) {
        FilterProviders.Providers.Remove(defaultFilterAttrProvider);
        FilterProviders.Providers.Add(
          new FilterAttributeFilterProvider(false /* do not cache */));
      }
      // ...
    }
  }

So, there you have it, a little trick that can allow you to upgrade that old ASP.NET MVC application to a newer MVC release, and buy you some time until you get to go through those old, custom action filters and fix their implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment