我正在使用ASP.NET Core(ASP.NET 5)Web API应用程序,并且必须在实体标签的帮助下实现HTTP缓存.早些时候我使用了CacheCow,但现在似乎不支持ASP.NET Core.我也没有找到任何其他相关的库或框架支持的详细信息.
我可以编写相同的自定义代码,但之前我想看看是否有任何可用的.请分享一些可用的东西,什么是更好的实现方式.
非常感谢.
解决方法
我也有同样的要求,但是
Bennie Wentzel’s anwser还没有完成,因为它仍然返回响应的正文.根据
spec 不应该.
经过一段时间的尝试使其与中间件一起工作,我发现MVC action filters实际上更适合这个功能.
public class ETagFilter : Attribute,IActionFilter { private readonly int[] _statusCodes; public ETagFilter(params int[] statusCodes) { _statusCodes = statusCodes; if (statusCodes.Length == 0) _statusCodes = new[] {200}; } public void OnActionExecuting(ActionExecutingContext context) { } public void OnActionExecuted(ActionExecutedContext context) { if (context.HttpContext.Request.Method == "GET") { if (_statusCodes.Contains(context.HttpContext.Response.StatusCode)) { //I just serialize the result to JSON,could implement IEquality<> for better performance. var content = context.Result.ToJson(); var etag = ETagGenerator.GetETag(context.HttpContext.Request.Path.ToString(),Encoding.UTF8.GetBytes(content)); if (context.HttpContext.Request.Headers.Keys.Contains("If-None-Match") && context.HttpContext.Request.Headers["If-None-Match"].ToString() == etag) { context.Result = new StatusCodeResult(304); } context.HttpContext.Response.Headers.Add("ETag",new[] { etag }); } } } }
然后将其用作您想要的动作或控制器作为属性:
[HttpGet] [Route("/api/data/")] [ETagFilter(200)] public async Task<IActionResult> GetDataFromApi() { ... }
这两种方法之间的重要区别在于,您的中间件可以在MVC middlware之前和之后运行,并且只能使用HttpContext.一旦MVC开始将响应发送回客户端,为时已晚,无法进行任何更改.
另一方面,动作过滤器是MVC中间件的一部分.他们可以访问MVC上下文,在这种情况下,实现此功能更为简单. More on Filters及其在MVC中的管道.