2017-08-30 142 views
0

我想缓存我的web api的响应直到一个特定的时间,而不是特定的时间。为此,我想使用某种到期头。截至目前我用的是“Microsoft.AspNetCore.ResponseCaching”包装的“ResponseCache中”属性在我的操作是这样的:ASP.NET核心Web API响应与过期缓存头缓存

[ResponseCache(Duration = 50)]

我之所以想用过期是空气污染指数只提供GET方法,数据是静态的(每天刷新一次)。有没有可能实现这样的事情?:

[ResponseCache(Expires = 00:00AM)] 

回答

0

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

有一个社区建立的替代方案,为您提供所需的功能。 https://github.com/KevinDockx/HttpCacheHeadershttps://www.nuget.org/packages/Marvin.Cache.Headers

难道你不能也将持续时间设置为60 * 60 * 24(#SecondsInADay)吗?或者您的数据需要在一天中的某个确切时间刷新?

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

事情是这样的:

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

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

Unforunately,它变得有点棘手。即使尚未将响应主体发送到服务器,也不能在响应主体已经写入之后修改响应标头。

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

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写入它之后劫持响应。