ASP.Net Core 2.0-ResponseCaching中间件-服务器上不缓存 [英] ASP.Net Core 2.0 - ResponseCaching Middleware - Not Caching on Server

查看:184
本文介绍了ASP.Net Core 2.0-ResponseCaching中间件-服务器上不缓存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将服务器端响应缓存(输出缓存)与asp.net core 2.0一起使用,并了解到

I want to use server-side response caching (output cache) with asp.net core 2.0 and found out about Response Caching Middleware and wanted to give it a try with a brand new asp.core mvc project.

这是上面链接的描述,这使我认为它可以像输出缓存一样使用.

Here is the description from the link above which makes me think this could be used like output cache.

中间件确定响应何时可缓存,存储响应并提供来自缓存的响应.

The middleware determines when responses are cacheable, stores responses, and serves responses from cache.

这是我的startup.cs的样子.

Here is how my startup.cs looks like.

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddResponseCaching();
        services.AddMvc();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseResponseCaching();

        if (env.IsDevelopment())
        {
            app.UseBrowserLink();
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

这是HomeController.cs

and here is the HomeController.cs

[ResponseCache(Duration = 60)]
public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View();
    }

    public IActionResult About()
    {
        ViewData["Message"] = "Your application description page.";

        return View();
    }

    public IActionResult Contact()
    {
        ViewData["Message"] = "Your contact page.";

        return View();
    }

    public IActionResult Error()
    {
        return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
    }
}

_Layout.cshtml文件的底部还有一个时间戳,以便我可以知道何时呈现页面,如下所示.

there is also a timestamp at the bottom of _Layout.cshtml file so i can tell when the page is rendered, like below.

<p>&copy; 2018 - ResponseCachingMiddleware - @DateTime.UtcNow</p>

Cache-Control标头似乎很好,这是我在加载页面时获得的标头,但是时间戳每次刷新一次都会不断更新.

Cache-Control headers seem to be fine, this is what I get in headers when I load the page but time stamp keeps getting updated on every refresh every second.

Cache-Control:public,max-age=60

我从MS文档中了解的是响应缓存中间件是服务器端缓存机制,它负责在

What I'm understanding from MS documentations is Response Caching Middleware is the server-side caching mechanism that takes care of caching the response while Response Caching seems to be just a filter to manipulate response headers for caching.

无法判断我的理解或代码是否有问题,我想抱怨自从我开始使用ASP.Net Core进行原型设计以来,我经常感到这种感觉.也许您还可以建议更好的资源作为副主题.

Can't tell if there is something wrong with my understanding or code and I wanna complain that I'm feeling this way too often since I started prototyping with ASP.Net Core. Maybe you could also suggest better resources as a side topic.

我之前已经签出了该帖子 ASP.NET Core 2.0-Http响应缓存中间件-没有缓存

I've checked out this post before ASP.NET Core 2.0 - Http Response Caching Middleware - Nothing cached

也检查了一下,但似乎唯一的区别是我正在使用mvc. https://github.com/aspnet/ResponseCaching/blob/dev/samples/ResponseCachingSample/Startup.cs

Also checked this out but it seems like the only difference is I'm using mvc. https://github.com/aspnet/ResponseCaching/blob/dev/samples/ResponseCachingSample/Startup.cs

谢谢

我在输出窗口中看到以下消息,除了我已经检查过响应缓存中间件的几个地方之外,在Google上找不到任何有关此消息的消息.

I'm seeing the message below in the output window, cannot find anything about it on google except the few places I already checked for response caching middleware.

Microsoft.AspNetCore.ResponseCaching.ResponseCachingMiddleware:信息: 无法为此请求缓存响应.

Microsoft.AspNetCore.ResponseCaching.ResponseCachingMiddleware:Information: The response could not be cached for this request.

注意:我希望我可以创建#response-caching-middleware标签.不确定#responsecache是​​否相关.

Note: I wish I could create #response-caching-middleware tag. Not sure #responsecache is relevant.

推荐答案

我最近也有同样的困惑.

I had this same confusion recently.

ASP.Net Core的ResponseCaching确实提供了客户端缓存(通过HTTP响应标头)和服务器端(如果响应在缓存中,则通过内存缓存的中间件使其他中间件短路).服务器端部分读取HTTP响应缓存头,以确定是否应进行服务器端缓存(类似于ISP或CDN可能执行的操作).

ASP.Net Core's ResponseCaching does provide both client-side caching (through HTTP response headers) & server-side (through a memory cache'd middleware that short-circuits other middlewares if the response is in the cache). The server-side portion reads the HTTP response cache headers to determine if it should do server-side caching (similar to what an ISP or CDN might do).

不幸的是,调试服务器端ResponseCaching很棘手,因为它具有怪异的规则&没有足够的日志记录.就我而言,我提取了Microsoft的源代码以逐步完成&找到我的代码存在的问题.

Unfortunately, debugging the server-side ResponseCaching is tricky because it has weird rules & there's not adequate logging. In my case I pulled 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.

请求的服务器端缓存分为两部分.服务器必须在第一次请求url时准备好缓存.它将第二次请求缓存的版本.请注意错误消息出现的时间(如果是第一个或第二个请求).它将告诉您它是否无法存储在缓存中,或者是否无法从缓存中检索.

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.

存储和存储的规则检索在此源代码文件中: https://github./ResponseCaching/blob/3bf5f6a1ce69b65c998d6f5c739822a9bed4a67e/src/Microsoft.AspNetCore.ResponseCaching/Internal/ResponseCachingPolicyProvider.cs

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

您的"Cache-Control:public,max-age = 60"标头应与这些规则完全匹配.

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

我的猜测是您实际上已在运行它,但不知道如何正确测试它. 在本期中提到了ResponseCaching的违反直觉的部分: https://github.com/aspnet/Home/issues/2607 本质上,如果浏览器发送无缓存或无存储标头(当您按CTRL + F5或打开调试器工具时),ASP.Net Core的ResponseCaching将接受浏览器的请求.重新生成响应.

My guess is you actually had it working, but didn't know how to test it correctly. There is a counter-intuitive portion of ResponseCaching noted in this issue: https://github.com/aspnet/Home/issues/2607 Essentially, if the browser sends a no-cache or no-store header (when you hit CTRL+F5 or have your debugger tools open), ASP.Net Core's ResponseCaching will honor the browser's request & re-generate the response.

因此,要测试您的代码是否正常工作,您可能加载了页面,从而启动了缓存,然后按CTRL + F5强制刷新浏览器&您希望服务器端以缓存的条目作为响应,而不是运行WebAPI代码.但是,它尊重无缓存请求标头&绕过缓存(并在输出日志中写入该消息).

So, to test if your code was working you probably loaded the page, which primed the cache, then you hit CTRL+F5 to force-refresh your browser & you expected the server-side to respond with a cached entry rather than running your WebAPI code. However, it honored the no-cache request header & bypassed the cache (& wrote that message in your output log).

测试此方法的方法是清除请求之间的浏览器缓存(或切换为隐身模式),而不是使用CTRL + F5.

The way to test this would be to clear your browser cache in-between requests (or switch to incognito), rather than using CTRL+F5.

另一方面,由于ASP.Net Core的ResponseCache很可能会由拥有响应的服务器而不是像中间缓存这样的服务器使用,因此遵守no-cache/no-store请求标头可能是一个糟糕的设计选择. CDN/ISP.我已经对基本ResponseCache进行了扩展,提供了一个禁用这些标头的选项(以及将缓存序列化到磁盘上,而不是仅在内存中).这是默认缓存的便捷替代.

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.

您可以在这里找到我的扩展名: https://github.com/speige/AspNetCore.ResponseCaching.Extensions https://www.nuget.org/packages/AspNetCore.ResponseCaching.Extensions

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

还有其他一些带有ResponseCaching的陷阱,请注意您在发布的博客URL中可能已经读过的内容.已验证的请求和带有set-cookie的响应将不会被缓存.仅使用GET或HEAD方法的请求将被缓存.如果QueryString不同,它将创建一个新的缓存条目.另外,通常,如果请求的某些条件与先前缓存的请求不同(例如:用户代理,接受编码等),通常您会希望使用"Vary"标头来防止缓存.最后,如果中间件处理了请求,它将使后面的中间件短路.确保在app.UseMVC()之前注册了app.UseResponseCaching()

There are also a few other other gotchas with ResponseCaching to watch out for which you may have already read about in the blog urls you posted. 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). Finally, if a Middleware handles a request it'll short-circuit later Middlewares. Make sure your app.UseResponseCaching() is registered before app.UseMVC()

这篇关于ASP.Net Core 2.0-ResponseCaching中间件-服务器上不缓存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆