Reputation: 133
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
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
Reputation: 924
There are a few steps to getting the ResponseCaching to function:
AddResponseCaching()
and UseResponseCaching()
in Startup.cs correctlyCache-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.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 secondsMicrosoft.AspNetCore.ResponseCaching.ResponseCachingMiddleware
which will output the reason it isn't caching the requestIn 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
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
Reputation: 17049
To set up response caching in dotnet core follow these steps:
In Startup.cs locate the ConfigureServices
method and add the following line:
services.AddResponseCaching();
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();
});
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
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