【问题标题】:Setting HTTP cache control headers in Web API在 Web API 中设置 HTTP 缓存控制标头
【发布时间】:2013-04-01 10:32:03
【问题描述】:

在 WebAPI 中为公共缓存服务器设置缓存控制标头的最佳方法是什么?

我对我的服务器上的 OutputCache 控件不感兴趣,我希望控制 CDN 端及其他端的缓存(我有单独的 API 调用,其中可以无限期缓存给定 URL 的响应)但我的一切'到目前为止,我已经阅读了 WebAPI 的预发布版本(因此引用了似乎不再存在的东西,例如 System.Web.HttpContext.Current.Reponse.Headers.CacheControl),或者仅设置几个 http 似乎非常复杂标题。

有没有简单的方法来做到这一点?

【问题讨论】:

    标签: c# asp.net-web-api http-caching


    【解决方案1】:

    如果有人在这里寻找专门针对 ASP.NET Core 的答案,您现在可以按照 @Jacob 的建议进行操作,而无需编写自己的过滤器。核心已经包含这个:

    [ResponseCache(VaryByHeader = "User-Agent", Duration = 1800)]
    public async Task<JsonResult> GetData()
    {
    }
    

    https://docs.microsoft.com/en-us/aspnet/core/performance/caching/response

    【讨论】:

    • 您在持续时间后缺少右括号 ) :)
    【解决方案2】:

    按照 cmets 中的建议,您可以创建一个 ActionFilterAttribute。这是一个只处理 MaxAge 属性的简单方法:

    public class CacheControlAttribute : System.Web.Http.Filters.ActionFilterAttribute
    {
        public int MaxAge { get; set; }
    
        public CacheControlAttribute()
        {
            MaxAge = 3600;
        }
    
        public override void OnActionExecuted(HttpActionExecutedContext context)
        {
            if (context.Response != null)
                context.Response.Headers.CacheControl = new CacheControlHeaderValue()
                {
                    Public = true,
                    MaxAge = TimeSpan.FromSeconds(MaxAge)
                };
    
            base.OnActionExecuted(context);
        }
    }
    

    然后你可以将它应用到你的方法中:

     [CacheControl(MaxAge = 60)]
     public string GetFoo(int id)
     {
        // ...
     }
    

    【讨论】:

    • 这个机会只针对客户端?对于服务器缓存,我应该 Strathweb.CacheOutput.WebApi2 将属性设置为 any ,rigth ?
    【解决方案3】:

    像 this answer 建议过滤器一样,考虑“扩展”版本 -- http://www.strathweb.com/2012/05/output-caching-in-asp-net-web-api/

    它曾经以 NuGet 包的形式提供 Strathweb.CacheOutput.WebApi2,但现在是 doesn't seem to be hosted anymore,现在位于 GitHub 上 -- https://github.com/filipw/AspNetWebApi-OutputCache

    【讨论】:

    • 我刚刚在 NuGet 中找到了它,但我想这可能是 VS 版本的东西。
    【解决方案4】:

    缓存控制头可以这样设置。

    public HttpResponseMessage GetFoo(int id)
    {
        var foo = _FooRepository.GetFoo(id);
        var response = Request.CreateResponse(HttpStatusCode.OK, foo);
        response.Headers.CacheControl = new CacheControlHeaderValue()
            {
                Public = true,
                MaxAge = new TimeSpan(1, 0, 0, 0)
            };
        return response;
    }
    

    【讨论】:

    • 这是我所知道的方法之一,但我希望有一些侵入性较小的方法,特别是不需要您从方法声明中删除有用信息的方法(来自特定的返回类型一个非常通用的不是一个很好的改变恕我直言)。无论如何,谢谢。
    • @Moo 你可以很容易地创建一个 ActionFilterAttribute 来完成这几行。就我个人而言,我只使用 HttpResponseMessage 作为我的返回类型,所以上述风格对我来说并不适用。 HTTP 是一个通用接口,因此在我的 API 层中反映这一点对我来说很有意义。
    • @Moo 如果您能通过查看签名来判断通过电线传输的内容,我可能会同意。但是,您不知道电线上发生了什么。它可能是 JSON,可能是对象的 XMLSerializer 序列化,也可能是对象的 DataContractSerialization。您不知道,除非您知道所有已安装的格式化程序,它们的设置顺序,接受标头的外观,格式化程序的限制是什么,等等。
    • 通过网络传出的只是一方的一半,我必须编写和维护这些东西,并将其交给其他开发人员。隐藏在方法块中而不是在声明中实际返回的内容意味着文档必须始终 100% 正确,而且我们知道这有多好,不是吗...
    • @VishnooRath 无论你使用属性路由还是常规路由都一样
    猜你喜欢
    • 1970-01-01
    • 2023-04-08
    • 2011-01-28
    • 2011-10-01
    • 2018-06-19
    • 1970-01-01
    • 1970-01-01
    • 2017-06-01
    • 2013-10-25
    相关资源
    最近更新 更多