ResponseCache not working in net core 3.1

Viewed 2663

I tried to learn about Response Caching in .NET Core 3.1. But it didn't work as I wished. I viewed the network in Chrome devtool, and it showed the response header with cache-control: no-cache, no-store.

I also found that Response header was with HeaderCacheControl{public,max-age=100} in Actionfilter. It was the value I expected, but the actual response header in browser is no-cache.

Startup class:

public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCaching(options=> 
    {
        options.SizeLimit = 1024;
        options.MaximumBodySize = 1024 * 1024 * 100;
        options.UseCaseSensitivePaths = false;
    });
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{   
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    app.UseCookiePolicy();
    app.UseStaticFiles();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseResponseCaching();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default", 
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

Controller:

[ResponseCache(Duration = 100, NoStore = false)]
public IActionResult Index()
{
   
    return View();
}
1 Answers

This is normal behaviour, there are multiple factors that plays on if the page is retrieved from disk cache or not.

I'll try to list common scenarios on which a user would request a page and if it's cached or not.

  1. AddResponseCaching and UseResponseCaching controls server side caching while ResponseCacheAttribute controls client side caching via setting the appropriate headers.

The way i like to control client side caching is by setting profiles like the following:

services.AddControllersWithViews(options =>
{
    options.CacheProfiles.Add("Caching", new CacheProfile()
    {
        Duration = 120,
        Location = ResponseCacheLocation.Any,
        VaryByHeader = "cookie"
    });
    options.CacheProfiles.Add("NoCaching", new CacheProfile()
    {
        NoStore = true,
        Location = ResponseCacheLocation.None
    });

})

and you use it like this:

[ResponseCache(CacheProfileName = "Caching")]
  1. Chrome prevents any kind of caching when using HTTPS without a certificate or when the certificate is invalid (in development you are prompted to trust the development cert in order to work over HTTPS)

  2. Browsers disable caching when dev tools are open, they usually send a Cache-Control: no-cache

  3. Hitting reload on chrome (Ctrl + F5) also disables cache and sends a Cache-Control: max-age=0 header with your request which is respected by the server.

  4. If you wish to test your cache if it's really working, do the following:

    1. Open your Chrome dev tools and uncheck the Disable cache checkbox if it's checked.

    2. Request your page like you normally would.

    3. Not try to request the same page via an anchor tag in the page that reference the same page (you should see that the page is retrieved from disk cache) (if the conditions below are respected).

    4. Also you can navigate to your (cache activated) page from another page, if it's cached it will be pulled from the disk cache (if the conditions below are respected).

  5. Pages with Forms and/or any kind of Authorization won't be cached. Pages with Antiforgery token included will be sent with Cache-Control and Pragma headers to no-cache. You can see all the conditions for caching on MSDN.

  6. Also some tools like Fiddler and Postman send no-cache header by default.

Related