C# tip: implementing a NoCache attribute for your ASP.NET MVC controller action methods
Posted: (EET/GMT+2)
Today I wanted to share with you a simple ASP.NET MVC 5 compatible action filter that easily lets to force the browser to re-read the results of a query instead of putting the received data into the browser cache.
I'm calling this action filter the "NoCache" filter, and this can then be used like just any other action filter to decorate your controller action methods. Here's the implementation code:
using System;
using System.Web;
using System.Web.Http.Filters;
using System.Web.Mvc;
namespace MyWebApp.Utilities
{
public class NoCacheAttribute : System.Web.Mvc.ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
filterContext.HttpContext.Response.Cache.SetExpires(
DateTime.UtcNow.AddDays(-1));
filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
filterContext.HttpContext.Response.Cache.SetRevalidation(
HttpCacheRevalidation.AllCaches);
filterContext.HttpContext.Response.Cache.SetCacheability(
HttpCacheability.NoCache);
filterContext.HttpContext.Response.Cache.SetNoStore();
base.OnResultExecuting(filterContext);
}
}
}
Above, I'm declaring a new class based on the library class ActionFilterAttribute from the System.Web.Mvc namespace. Note that the namespace System.Web.Http.Filters also contains a similarly names class, but we specifically want the MVC version here.
Now, the code shown above contains a single overridden method OnResultExecuting, which is fired when an action method marked with the NoCache attribute executes. It sets several different HTTP header options, and these in combination force the browser to always re-fetch the data from the server. This is useful in situations where the responses changes often, such as search results, multi-user system data, Ajax call results, etc.
If you don't do anything special in your MVC controller, the response HTTP headers contains a setting for cache control as follows:
Cache-Control: private
However, when you use the NoCache attribute as above, then the response header will contain these fields:
Cache-Control: no-cache, no-store, must-revalidate Pragma: no-cache Expires: -1
Hope this helps!