asp.net-web-api – 在ASP.NET Core Web API中实现HTTP缓存(ETag)

前端之家收集整理的这篇文章主要介绍了asp.net-web-api – 在ASP.NET Core Web API中实现HTTP缓存(ETag)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用ASP.NET Core(ASP.NET 5)Web API应用程序,并且必须在实体标签的帮助下实现HTTP缓存.早些时候我使用了CacheCow,但现在似乎不支持ASP.NET Core.我也没有找到任何其他相关的库或框架支持的详细信息.

我可以编写相同的自定义代码,但之前我想看看是否有任何可用的.请分享一些可用的东西,什么是更好的实现方式.

非常感谢.

解决方法

我也有同样的要求,但是 Bennie Wentzel’s anwser还没有完成,因为它仍然返回响应的正文.根据 spec 不应该.

经过一段时间的尝试使其与中间件一起工作,我发现MVC action filters实际上更适合这个功能.

在这个例子中,我借用了Bennie的ETag生成代码

  1. public class ETagFilter : Attribute,IActionFilter
  2. {
  3. private readonly int[] _statusCodes;
  4.  
  5. public ETagFilter(params int[] statusCodes)
  6. {
  7. _statusCodes = statusCodes;
  8. if (statusCodes.Length == 0) _statusCodes = new[] {200};
  9. }
  10.  
  11. public void OnActionExecuting(ActionExecutingContext context)
  12. {
  13. }
  14.  
  15. public void OnActionExecuted(ActionExecutedContext context)
  16. {
  17. if (context.HttpContext.Request.Method == "GET")
  18. {
  19. if (_statusCodes.Contains(context.HttpContext.Response.StatusCode))
  20. {
  21. //I just serialize the result to JSON,could implement IEquality<> for better performance.
  22. var content = context.Result.ToJson();
  23.  
  24. var etag = ETagGenerator.GetETag(context.HttpContext.Request.Path.ToString(),Encoding.UTF8.GetBytes(content));
  25.  
  26. if (context.HttpContext.Request.Headers.Keys.Contains("If-None-Match") && context.HttpContext.Request.Headers["If-None-Match"].ToString() == etag)
  27. {
  28. context.Result = new StatusCodeResult(304);
  29. }
  30. context.HttpContext.Response.Headers.Add("ETag",new[] { etag });
  31. }
  32. }
  33. }
  34. }

然后将其用作您想要的动作或控制器作为属性

  1. [HttpGet]
  2. [Route("/api/data/")]
  3. [ETagFilter(200)]
  4. public async Task<IActionResult> GetDataFromApi()
  5. {
  6. ...
  7. }

这两种方法之间的重要区别在于,您的中间件可以在MVC middlware之前和之后运行,并且只能使用HttpContext.一旦MVC开始将响应发送回客户端,为时已晚,无法进行任何更改.

另一方面,动作过滤器是MVC中间件的一部分.他们可以访问MVC上下文,在这种情况下,实现此功能更为简单. More on Filters及其在MVC中的管道.

猜你在找的.NET Core相关文章