带有过期标头的ASP.NET Core Web API响应缓存

时间:2017-08-30 12:46:45

标签: asp.net-core asp.net-core-webapi

我想在特定时间缓存我的web api的响应,而不是在特定时间。为此,我想使用某种过期标头。截至目前,我使用“Microsoft.AspNetCore.ResponseCaching”包和我的动作上的“ResponseCache”属性,如下所示:

[ResponseCache(Duration = 50)]

我想使用过期的原因是api只提供GET方法,数据是静态的(每天刷新一次)。有没有可能实现这样的东西?:

[ResponseCache(Expires = 00:00AM)]

1 个答案:

答案 0 :(得分:0)

不幸的是,没有.net核心中的ResponseCache属性的当前状态。希望将来能够得到改进。也许你可以在他们的回购中提交一个问题,这样有人就会知道对它进行编码&提交拉取请求?

社区建造的替代方案可为您提供所需的功能。 https://github.com/KevinDockx/HttpCacheHeaders https://www.nuget.org/packages/Marvin.Cache.Headers

你还没有将持续时间设置为60 * 60 * 24(#SecondsInADay)吗?或者您的数据是否需要在白天的确切时间刷新?

另一种选择是直接修改响应上下文头。这通常在自定义中间件中完成。

这样的事情:

app.Use(async (context, next) =>
{
    await next();

    context.Response.Headers["headerName"] = "headerValue";
});

不幸的是,它变得有点棘手。在已经写入响应主体后,即使没有将响应标头发送到服务器,也无法修改响应标头。

大多数中间件通过"填充" /"包装"来解决这个问题。响应主体的流。

public class ShimmedResponseContext
  {
    public HttpContext _httpContext { get; }
    private Stream _originalResponseStream { get; set; }
    private MemoryStream _shimmedResponseStream { get; set; }

    public ShimmedResponseContext(HttpContext httpContext)
    {
      _httpContext = httpContext;
    }

    public void ShimResponseStream()
    {
      _originalResponseStream = _httpContext.Response.Body;
      _shimmedResponseStream = new MemoryStream();
      _httpContext.Response.Body = _shimmedResponseStream;
    }

    public void UnshimResponseStream()
    {
      _shimmedResponseStream.Position = 0;
      _shimmedResponseStream.CopyTo(_originalResponseStream);
      _httpContext.Response.Body = _originalResponseStream;
    }
  }

  app.Use(async (context, next) =>
  {
    var shimmedContext = new ShimmedResponseContext(context);
    shimmedContext.ShimResponseStream();

    await next();

    context.Response.Headers[HeaderNames.CacheControl] = "public,expires=[your chosen date/time]";

    shimmedContext.UnshimResponseStream();
  });

另外,请确保在app.UseMVC()之前注册此中间件;在您的Startup.cs配置方法中,因为中间件按顺序运行&只有先前注册的中间件可以在稍后的Middelware编写后劫持响应。