11

I'd like to tell ASP.NET Core to add a common Cache-Control and related headers to all responses served by MVC controllers, both HTML pages and Web API responses. I don't want the policy to apply to cache static files; those I want to be cached.

In particular case, I want to disable caching, the equivalent of applying this attribute to all controllers:

[ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]

I could made a base controller with this attribute and derive all other controllers from it. I was wondering if there is a configuration-based approach that avoids the need for such a base controller.

3
  • 1
    Would using a Middleware be a feasible solution in your case? Commented Feb 7, 2017 at 19:15
  • I'm open to using middleware if it does the job. I would want it to play nicely with the MVC cache control features. For example, I'd like the flexibility that if in the future, i wanted to override the caching on a given MVC page, I could still use a ResponseCache attribute on the corresponding controller method, and it would take precedence. Commented Feb 7, 2017 at 19:51
  • davidpine.net/blog/asp-net-core-optimization Commented Feb 7, 2017 at 20:02

2 Answers 2

19

You can do it w/o middleware just by adding

services.AddMvc(options => {
    options.Filters.Add(new ResponseCacheAttribute() { NoStore = true, Location = ResponseCacheLocation.None });
})

in your ConfigureServices method. Works with any Attribute (i.e AuthorizeAttribute), which can be instantiated and will be applied to all controllers and actions. Also no need for a base class.

Sign up to request clarification or add additional context in comments.

4 Comments

Can you apply custom Attributes to individual controllers and methods to override the ConfigureServices setup if needed?
@Tseng, I first tried this months ago, and I thought it worked at the time. But when I tried it on a new ASP.NET Core Web application (the basic template from Visual Studio) and added your code, it didn't work. The site runs fine, but the cache headers are not output. Is there a newer method than the one you mentioned? Or can you get your technique to work starting from a new ASP.NET Core site?
I just tried it on a new ASP.NET Core site and it worked.
Check to see if you have services.AddMvc twice. Perhaps the second instance is overwriting the first.
1

As @DOMZE said, you may consider using a custom middleware. Actually, response caching is already implemented as a middleware.

But as you want to add caching only to all MVC actions, the better way is to use MVC action filters. One of the benefits is that you may apply filter only to specific controller/action + you will have access to ActionExecutingContext (controller instance/ action arguments )

public class ResponseCacheActionFilter : IActionFilter
{
     public void OnActionExecuting(ActionExecutingContext context)
     {
        // before the action executes
     }

     public void OnActionExecuted(ActionExecutedContext context)
     {
        // after the action executes
        // add here a common Cache-Control and related headers to all responses
     }
}

3 Comments

Would you have to apply the filter to every controller? If so, I don't see the advantage over using a ResponseCache attribute.
@EdwardBrey you may register filter as a global one
A limitation of inserting the headers yourself is that if you want to leave open the flexibility of using MVC ResponseCache attributes to override the default caching policy for certain pages, you have to code the coordination yourself.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.