简体   繁体   中英

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.

I have added the ResponseCaching middleware to the IServicesCollection in ConfigureServices method like this.

    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.

 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

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

Finally in my angular application I have setted Cache-control headers too.

  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. According to the Microsoft documentation that should work

Response Caching Middleware only caches server responses that result in a 200 (OK) status code. Any other responses, including error pages, are ignored by the middleware.

But when it runs it's caching 500 error responses too. 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.

Note

  • I tried with Chrome, Edge and IE browsers too.
  • I used ASP.NET Core 3.1
  • My Frontend application is 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. 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();
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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