简体   繁体   English

ASP.NET 核心响应缓存中间件 - 如何停止缓存 (500) 错误响应

[英]ASP.NET Core Response Caching Middleware - How to stop caching (500) error responses

I implemented ASP.NET Core Response Caching in my application to cache some API requests.我在我的应用程序中实现了 ASP.NET 核心响应缓存来缓存一些 API 请求。

I have added the ResponseCaching middleware to the IServicesCollection in ConfigureServices method like this.我已经像这样在 ConfigureServices 方法中将 ResponseCaching 中间件添加到 IServicesCollection 中。

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy("CorsPolicy",
            builder =>
            {
                builder.AllowAnyOrigin()
                       .AllowAnyHeader()
                       .AllowAnyMethod();

            });
        });

        services.AddResponseCaching();
        services.AddControllersWithViews();

        services.AddSpaStaticFiles(configuration =>
        {
            configuration.RootPath = "ClientApp/dist";
        });
    }

I have used it in Configure method like like this.我像这样在 Configure 方法中使用过它。

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }
        app.UseCors("CorsPolicy");
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        if (!env.IsDevelopment())
        {
            app.UseSpaStaticFiles();
        }

        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller}/{action=Index}/{id?}");
        });

        app.UseResponseCaching();

        app.Use(async (context, next) =>
        {
           context.Response.GetTypedHeaders().CacheControl =
              new Microsoft.Net.Http.Headers.CacheControlHeaderValue()
              {
                  Public = true,
                  MaxAge = TimeSpan.FromSeconds(apiConfiguration.CacheDuration),
              };

        context.Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Vary] = new string[] { "Accept-Encoding" };
     
            await next();
        });

        app.UseSpa(spa =>
        {
            spa.Options.SourcePath = "ClientApp";
            if (env.IsDevelopment())
            {
                spa.UseAngularCliServer(npmScript: "start");
            }
        });
    }

I have also decorated my Web API action methods with ResponseCache attribute like below我还用 ResponseCache 属性装饰了我的 Web API 操作方法,如下所示

    [HttpGet]
    [ResponseCache(Duration = 60)]
    public IActionResult Get(){
      //code
    }

Finally in my angular application I have setted Cache-control headers too.最后,在我的 angular 应用程序中,我也设置了缓存控制标头。

  fetchAPIData(){
    return this.http.get('https://localhost:44325/data',  {
      headers: new HttpHeaders({
        'Cache-Control': 'public',
        "Content-Type": "application/json"
      })
    });
  }

I want to cache server responses only with 200 (OK) status code.我只想缓存带有 200 (OK) 状态代码的服务器响应。 According to the Microsoft documentation that should work根据应该工作的Microsoft 文档

Response Caching Middleware only caches server responses that result in a 200 (OK) status code.响应缓存中间件仅缓存导致 200 (OK) 状态代码的服务器响应。 Any other responses, including error pages, are ignored by the middleware.中间件会忽略任何其他响应,包括错误页面。

But when it runs it's caching 500 error responses too.但是当它运行时它也会缓存 500 个错误响应。 look at below image看下面的图片在此处输入图像描述

  1. What can be the reason for this?这可能是什么原因?
  2. What should I do for fixing this.我该怎么做才能解决这个问题。 I just want to cache 200(OK) requests.我只想缓存 200(OK) 个请求。

Note笔记

  • I tried with Chrome, Edge and IE browsers too.我也尝试过 Chrome、Edge 和 IE 浏览器。
  • I used ASP.NET Core 3.1我用的是 ASP.NET Core 3.1
  • My Frontend application is Angular 7我的前端应用程序是 Angular 7

I had exactly the problem described in the question.我确实遇到了问题中描述的问题。 I'm using the ResponseCache attribute on a web api endpoint which can return either success or failure.我在 web api 端点上使用 ResponseCache 属性,它可以返回成功或失败。 I was getting cache headers for both success and failure of the call.我正在获取调用成功和失败的缓存标头。

I solved this by adding custom middleware to remove the cache headers in the failure case:我通过添加自定义中间件来解决这个问题,以删除失败案例中的缓存标头:

app.Use(async (context, next) =>
{
    // Do not cache error conditions
    context.Response.OnStarting(() =>
    {
        if (context.Response.StatusCode >= 400)
        {
            context.Response.Headers.Remove("Cache-Control");
        }
        return Task.FromResult(0);
    });
    await next();
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM