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

C# ASP.NET核心响应缓存中间件-如何停止缓存(500)错误响应,c#,asp.net-core,asp.net-core-webapi,responsecache,C#,Asp.net Core,Asp.net Core Webapi,Responsecache,我在应用程序中实现了ASP.NET核心响应缓存,以缓存一些API请求 我在ConfigureServices方法中将ResponseCaching中间件添加到IServiceCollection中,如下所示 public void ConfigureServices(IServiceCollection services) { services.AddCors(options => { options.AddPolic

我在应用程序中实现了ASP.NET核心响应缓存,以缓存一些API请求

我在ConfigureServices方法中将ResponseCaching中间件添加到IServiceCollection中,如下所示

    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";
        });
    }
 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");
            }
        });
    }
我在像这样的配置方法中使用了它

    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";
        });
    }
 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");
            }
        });
    }
我还用ResponseCache属性修饰了我的WebAPI操作方法,如下所示

    [HttpGet]
    [ResponseCache(Duration = 60)]
    public IActionResult Get(){
      //code
    }
最后,在我的angular应用程序中,我也设置了缓存控制头

  fetchAPIData(){
    return this.http.get('https://localhost:44325/data',  {
      headers: new HttpHeaders({
        'Cache-Control': 'public',
        "Content-Type": "application/json"
      })
    });
  }
我只想缓存状态代码为200(OK)的服务器响应。根据法律,这应该行得通

响应缓存中间件仅缓存结果为的服务器响应 状态代码为200(正常)。任何其他响应,包括错误页面, 被中间件忽略

但当它运行时,它也会缓存500个错误响应。请看下图

  • 这是什么原因呢
  • 我该怎么做才能修好这个。我只想缓存200个(OK)请求
  • 注意

    • 我也尝试了Chrome、Edge和IE浏览器
    • 我使用了ASP.NETCore3.1
    • 我的前端应用程序是Angular 7

    尝试在相应控制器中为错误操作方法添加[ResponseCache(Duration=0,Location=ResponseCache.None,NoStore=true)]。Hi@Thilina Sandunsiri,我无法重现您的问题。move
    app.UseResponseCaching()怎么样
    before
    app.UseEndpoints
    ?@Lakshitha这是一个用于GET请求的Web API操作方法。因此,如果我设置“Location=ResponseCacheLocation.None”,则相同的方法返回成功/错误响应,然后将缓存控制响应头设置为“no Cache”,如果我设置“NoStore=true”,则将缓存控制响应头设置为“no store”。所以在这两种情况下,它都不会缓存任何响应(即使是成功的)@Lakshitha,如果我设置“Duration=0”,那么缓存控制响应头的最大年龄将变为0。这意味着缓存在收到响应后立即过期。所以每个请求,浏览器都会请求一个新版本的API响应。所以每次新的API调用都会发送到服务器。实际上,我想缓存成功的(200)个API调用并忽略错误响应,比如500400,400@ThilinaSandunsiri. 它应该在错误操作方法上设置。(必须有单独的操作)根据您的代码,所有错误都将重定向到相应控制器中的错误操作方法。app.UseExceptionHandler(“/Error”);因此,应该在错误操作方法上设置no缓存。