Devloper
Devloper

Reputation: 133

Response cache not working in asp.net core project

I try to implement Response cache in asp.net core project but its not working.This is startup.cs:

public void ConfigureServices(IServiceCollection services) 
{
  services.AddResponseCaching();
  services.AddMvc();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env) 
{
    app.UseResponseCaching();

    if (env.IsDevelopment()) 
    {
      app.UseDeveloperExceptionPage();
    }

And this is my controller.

[ResponseCache(Duration = 30)]
public IActionResult Index() 
{
  ViewBag.IsMobile = RequestExtensions.IsMobileBrowser(ContextAccessor.HttpContext.Request);
  return View();
}

But still cache control header id

cache-control →no-cache, no-store

Where I am lacking please help. This response cache is not working and I take guidance from Microsoft document.

Upvotes: 11

Views: 13355

Answers (5)

Zanyar Jalal
Zanyar Jalal

Reputation: 1894

Must your action is GET method

Add HttpGet attribute for your action

[ResponseCache(Duration = 30)]
[HttpGet] // <---- 
public IActionResult Index() 
{
  ViewBag.IsMobile = RequestExtensions.IsMobileBrowser(ContextAccessor.HttpContext.Request);
  return View();
}

Upvotes: 0

Zout
Zout

Reputation: 924

There are a few steps to getting the ResponseCaching to function:

  1. You need to call AddResponseCaching() and UseResponseCaching() in Startup.cs correctly
  2. The page must return a Cache-Control header e.g. Cache-Control: public,max-age=60 (Note that it MUST contain the public directive). You can do this via the [ResponseCache] attribute, manually adding it to the response headers, etc.
  3. Method must be GET or HEAD, status code must be 200
  4. Authorization request header must not be present
  5. If the client sends up their own cache-control header in the request, it must be valid - i.e. if the client passes up Cache-Control: max-age=0 (which Chrome/Firefox/etc do if the user presses F5) then the response will never be served from the cache because anything cached is by definition older than 0 seconds
  6. Various other conditions. I recommend making sure you can see debug-level logs from Microsoft.AspNetCore.ResponseCaching.ResponseCachingMiddleware which will output the reason it isn't caching the request

In my case, I wanted to ignore the client request Cache-Control header, so I added a subclass of ResponseCachingPolicyProvider like so:

    /// <summary>
    /// By default, <see cref="ResponseCachingPolicyProvider"/> will not return a cached response
    /// if the client sends up a Cache-Control header indicating the client wants a fresh
    /// response. This is according to HTTP spec but is not the behavior we want, so
    /// we will remove the client's specified Cache-Control header while evaluating whether
    /// or not we should return the cached response for this request.
    /// </summary>
    public class CustomResponseCachingPolicyProvider : ResponseCachingPolicyProvider
    {
        public override bool IsCachedEntryFresh(ResponseCachingContext context)
        {
            var reqCacheControl = context.HttpContext.Request.Headers[HeaderNames.CacheControl];
            context.HttpContext.Request.Headers.Remove(HeaderNames.CacheControl);
            var result = base.IsCachedEntryFresh(context);
            context.HttpContext.Request.Headers.Add(HeaderNames.CacheControl, reqCacheControl);
            return result;
        }
    }

If the request is being served from the memory cache, it will add an Age header to the response which you can check to verify the caching is functioning as expected.

Upvotes: 1

sanmolhec
sanmolhec

Reputation: 416

Beware that for the cache to work must meet a number of requirements:

The request must result in a 200 (OK) response from the server.

The request method must be GET or HEAD.

Terminal middleware, such as Static File Middleware, must not process the response prior to the Response Caching Middleware.

The Authorization header must not be present.

Cache-Control header parameters must be valid, and the response must be marked public and not marked private.

The Pragma: no-cache header/value must not be present if the Cache-Control header is not present, as the Cache-Control header overrides the Pragma header when present. The Set-Cookie header must not be present.

Vary header parameters must be valid and not equal to *.

The Content-Length header value (if set) must match the size of the response body.

...

See this website: aspnet-core-response-cache

And beware also that if the request is being made from Postman disable the option "do not send the cache header".

See this post (image of end post): ASP.Net Core 2.0 - ResponseCaching Middleware - Not Caching on Server

Upvotes: 15

Denys Wessels
Denys Wessels

Reputation: 17049

To set up response caching in dotnet core follow these steps:

  1. In Startup.cs locate the ConfigureServices method and add the following line:

    services.AddResponseCaching();

  2. Ins Startup.cs locate the Configure method and add the following lines:

        app.UseResponseCaching();
    
        app.Use(async (context, next) =>
        {
            context.Response.GetTypedHeaders().CacheControl =
                new Microsoft.Net.Http.Headers.CacheControlHeaderValue()
                {
                    Public = true,
                    MaxAge = TimeSpan.FromSeconds(10)
                };
            context.Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Vary] =
                new string[] { "Accept-Encoding" };
    
            await next();
        });
    
  3. Apply the [ResponseCache] attribute to the action which requires caching:

    [ResponseCache(Duration = 300, VaryByQueryKeys = new string[] { "id" })]
    [HttpGet]
    public async Task<IActionResult> Index(int id)
    {
        return View();
    }
    

Upvotes: 4

darcane
darcane

Reputation: 483

I tried this Microsoft document and successfully cached.

Cache-Control: public,max-age=30
Date: Thu, 27 Dec 2018 07:50:16 GMT

I think you are missing the app.Use(async => ) part.

Upvotes: 2

Related Questions