ASP.Net Core 2.0 - ResponseCaching中间件 - 不在服务器上缓存

Eng*_*gin 7 asp.net caching outputcache responsecache asp.net-core-2.0

我想在asp.net core 2.0中使用服务器端响应缓存(输出缓存)并找到有关响应缓存中间件的信息,并希望尝试使用全新的asp.core mvc项目.

这是上面链接的描述,这让我觉得这可以像输出缓存一样使用.

中间件确定响应何时可缓存,存储响应以及从缓存提供响应.

这是我的startup.cs的样子.

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?}");
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

这是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 });
    }
}
Run Code Online (Sandbox Code Playgroud)

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

<p>&copy; 2018 - ResponseCachingMiddleware - @DateTime.UtcNow</p>
Run Code Online (Sandbox Code Playgroud)

Cache-Control标题看起来很好,这是我在加载页面时在标题中得到的,但时间戳每秒刷新一次.

Cache-Control:public,max-age=60
Run Code Online (Sandbox Code Playgroud)

我从MS文档中理解的是响应缓存中间件是服务器端缓存机制,它负责缓存响应,而响应缓存似乎只是一个操作缓存响应头的过滤器.

无法判断我的理解或代码是否有问题,我想抱怨自从我开始使用ASP.Net Core进行原型设计以来,我经常会这样.也许你也可以建议更好的资源作为一个侧面话题.

我在ASP.NET Core 2.0之前检查了这篇文章 - Http Response Caching Middleware - Nothing cached

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

谢谢

编辑:我在输出窗口中看到下面的消息,除了我已经检查过响应缓存中间件的几个地方之外,在谷歌上找不到任何关于它的信息.

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

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

Dev*_*ner 12

我最近也有同样的困惑.

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

不幸的是,调试服务器端的ResponseCaching很棘手,因为它有很奇怪的规则并且没有足够的日志记录.在我的情况下,我下载了微软的源代码来逐步完成它并找到我的代码的问题.

您在输出窗口"无法为此请求缓存响应"中找到的注释是一个线索.

服务器端缓存请求有两个部分.服务器必须在第一次请求URL时填充缓存.它将在第二次请求时提供缓存版本.注意错误消息何时显示,如果它在第一个或第二个请求上.这将告诉您它是否无法存储在缓存中或无法从缓存中检索.

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

你的"Cache-Control:public,max-age = 60"标题应该符合这些规则.

我的猜测是你实际上有它工作,但不知道如何正确测试它.本期中提到了一个反直觉的ResponseCaching部分:https://github.com/aspnet/Home/issues/2607 基本上,如果浏览器发送无缓存或无存储头(当你点击CTRL +时) F5或打开你的调试工具),ASP.Net Core的ResponseCaching将尊重浏览器的请求并重新生成响应.

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

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

另外,尊重no-cache/no-store请求标头可能是一个糟糕的设计选择,因为ASP.Net Core的ResponseCache很可能被拥有响应的服务器使用,而不是像CDN /那样的中间缓存ISP.我已经扩展了基本的ResponseCache,并选择了禁用这些头文件(以及将缓存序列化为磁盘,而不是仅限内存).它是默认缓存的简单替代品.

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

还有一些其他的问题与ResponseCaching一起注意你可能已经在你发布的博客网址中读到过的内容.使用set-cookie的经过身份验证的请求和响应将不会被缓存.仅缓存使用GET或HEAD方法的请求.如果QueryString不同,它将创建一个新的缓存条目.此外,如果请求的某些条件与先前缓存的请求不同(例如:user-agent,accept-encoding等),通常您会想要一个"Vary"标头来阻止缓存.最后,如果一个中间件处理一个请求,它将在以后的中间件短路.确保你的app.UseResponseCaching()在app.UseMVC()之前注册


Cod*_*orm 11

我有同样的问题,我正要拉我的头发了它,你可以设置app.UseResponseCaching();以及services.AddResponseCaching();添加ResponseCache,对我的行动正好就是在微软官方文档说的顶部,尽管在cache-controll设置正确的响应返回头从服务器端但仍未在服务器端缓存.

在这个问题出汗几个小时之后,我发现问题出现的地方以及为什么没有在服务器上缓存.

默认情况下,浏览器cache-controllmax-age=0为请求设置值(如果请求不是由后向或前向引起的),即使您cache-controller在响应中通过ResponseCache在操作(或控制器)之上添加属性来正确设置,因为cache-controller请求发送的设置为max-age=0,服务器无法缓存响应,我认为这也必须添加到响应缓存限制列表中

无论如何,您可以通过在调用之前添加几行代码来覆盖浏览器默认行为,app.UseResponseCaching();另一方面,您需要在调用之前添加自定义中间件来修改请求cache-control标头值app.UseResponseCaching();.

看下面的代码,为我工作也希望为你工作

 app.Use(async (ctx, next) =>
        {
            ctx.Request.GetTypedHeaders().CacheControl = new Microsoft.Net.Http.Headers.CacheControlHeaderValue()
            {
                Public = true,
                MaxAge = TimeSpan.FromSeconds(60)
            };
            await next();
        }
            );
        app.UseResponseCaching();
Run Code Online (Sandbox Code Playgroud)

为确保ResponseCaching按预期工作,您也可以使用邮递员,但必须在设置中将"发送无缓存标题"设置为关闭,请参见下图

在此输入图像描述