ASP.NET Core 2.0 - Http Response Caching Middleware - Nothing cached

穿精又带淫゛_ 提交于 2019-12-24 16:49:22

问题


I created a new solution from WebApi .Net Core 2.0 template in Visual Studio. I added the following in startup.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    services.AddHttpCacheHeaders(opt => opt.MaxAge = 600);
    services.AddResponseCaching();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseResponseCaching();
    app.UseHttpCacheHeaders();
    app.UseMvc();
}

Then, with postman, I hit http://localhost:xxxx/api/values which is a endpoint created by the template and that returns ["value1","value2"]

Note that I made sure that Postman doesn't send no-cache header (in Postman settings).

The HttCacheHeaders service comes from that repo. It adds HTTP Cache Headers. So my endpoint response header is:

  • Cache-Control: public,max-age=600
  • Content-Type: application/json; charset=utf-8
  • Date: Fri, 29 Sep 2017 14:02:29 GMT
  • ETag: C5DFA8974BB722D27E71EE50D3D14625
  • Expires: Fri, 29 Sep 2017 14:03:29 GMT
  • Last-Modified: Fri, 29 Sep 2017 14:02:29 GMT
  • Server: Kestrel
  • Transfer-Encoding: chunked
  • Vary: Accept, Accept-Language, Accept-Encoding
  • X-Powered-By: ASP.NET
  • X-SourceFiles: =?UTF-8?B?................

The problem is that nothing gets cached. the Ouput windows only shows The response could not be cached for this request.

So I'm a bit lost on how to use ASP.NET Core ResponseCaching Middleware.

Update

If I don't use the HttCacheHeaders service but add [ResponseCache(Duration = 600)] to the action of my controller, the cache works.
Note that reason that I want to use HttCacheHeaders is for ETag and Last-Modified to later do Validation Caching as well as Expiration Caching.


回答1:


This is kind of a non-answer, with some troubleshooting tips.

I tried your exact code & it worked fine for me. Maybe a bug has been fixed in the HttpCacheHeaders or ResponseCaching repo?

Unfortunately, debugging the server-side ResponseCaching is tricky because it has weird rules & there's not adequate logging. When I've had similar issues with it in the past I've had to pull down Microsoft's source code to step through it & find the issue with my code.

The note you found in the output window "The response could not be cached for this request" is a clue.

There's 2 parts to the server-side caching of a request. The server has to prime the cache the first time the url is requested. It will serve the cached version the 2nd time it's requested. Pay attention to when the error message shows up, if it's on the 1st or 2nd request. That'll tell you if it couldn't be stored in the cache or if it couldn't be retrieved from the cache.

The rules for both storage & retrieval are in this source code file: https://github.com/aspnet/ResponseCaching/blob/3bf5f6a1ce69b65c998d6f5c739822a9bed4a67e/src/Microsoft.AspNetCore.ResponseCaching/Internal/ResponseCachingPolicyProvider.cs

Your "Cache-Control:public,max-age=600" header should match these rules just fine.

You already found the no-cache/no-store "gotcha". There are also a few other others with ResponseCaching to watch out for:

Authenticated requests & responses with set-cookie won't be cached. Only requests using GET or HEAD method will be cached. If the QueryString is different, it'll make a new cache entry. Also, usually you'll want a "Vary" header to prevent caching if certain conditions of a request differ from the previously-cached request (example: user-agent, accept-encoding, etc).

On a side note, honoring the no-cache/no-store request headers was probably a poor design choice since ASP.Net Core's ResponseCache will most likely be used by a server who owns the response, rather than an intermediary cache like a CDN/ISP. I've extended the base ResponseCache with an option to disable honoring these headers (as well as serialize the cache to disk, rather than in-memory only). It's an easy drop-in replacement for the default cache.

You can find my extension here: https://github.com/speige/AspNetCore.ResponseCaching.Extensions https://www.nuget.org/packages/AspNetCore.ResponseCaching.Extensions




回答2:


HttpCacheHeader is not a cache store.

This middleware handles the "backend"-part: it generates the correct cache-related headers, and ensures a cache can check for expiration (304 Not Modified) & preconditions (412 Precondition Failed) (often used for concurrency checks).

Source



来源:https://stackoverflow.com/questions/46492736/asp-net-core-2-0-http-response-caching-middleware-nothing-cached

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!