7

I have a global NoCache filter as shown here: https://stackoverflow.com/a/12964123/78739

This global no cache filter applies to all actions. I have a case where I need to allow caching for one particular action using OutputCacheAttribute. I was thinking in the NoCache filter I would check to see if the action that has just executed has the OutputCacheAttribute. If it does, it does NOT apply the no cache settings. So for example, my code would be:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public sealed class NoCacheAttribute : FilterAttribute, IResultFilter
{
    public void OnResultExecuted(ResultExecutedContext filterContext)
    {
        if (/* action does not have OutputCacheAttribute */)
        {
            var cache = filterContext.HttpContext.Response.Cache;
            cache.SetCacheability(HttpCacheability.NoCache);
            cache.SetRevalidation(HttpCacheRevalidation.ProxyCaches);
            cache.SetExpires(DateTime.Now.AddYears(-5));
            cache.AppendCacheExtension("private");
            cache.AppendCacheExtension("no-cache=Set-Cookie");
            cache.SetProxyMaxAge(TimeSpan.Zero);
        }
    }
}

The problem is I don't know how to get the action and its attributes from the ResultExecutedContext variable that is passed into the OnResultExecuted method.

Community
  • 1
  • 1
iheartcsharp
  • 1,279
  • 1
  • 14
  • 22

2 Answers2

4

This answer is for MVC4 since MVC5 has filter overrides

There doesn't seem to be a clean way (I avoid reflection. Yuck!) to get the ActionDescriptor from OnResultExecuted

Contrary to the non-accepted answer in SO link you gave, OutputCacheAttribute does control client cache so:

in the global

filters.Add(new OutputCacheAttribute { Location = OutputCacheLocation.None, NoStore = true });

Then in the action

//The OutputCacheAttribute in the global filter won't be called
//Only this OutputCacheAttribute is called since AllowMultiple in OutputCacheAttribute is false
[[OutputCacheAttribute(Location = OutputCacheLocation.Server, Duration = 100)]
public ActionResult Index()
{
    return View();
}

Check the response headers to verify

LostInComputer
  • 15,188
  • 4
  • 41
  • 49
  • filter overrides are of limited use because they don't allow you to selectively override filters. they force you to cull all filters of a certain type, which may not be what you want – Martin Capodici Jul 11 '19 at 05:21
0

Try this

filterContext.Controller.GetType().GetMethod(action).GetCustomAttributes(typeof(OutputCacheAttribute), true).Length == 0
shenku
  • 11,969
  • 12
  • 64
  • 118