【问题标题】:How to determine if an HttpResponseMessage was fulfilled from cache using HttpClient如何确定是否使用 HttpClient 从缓存中完成了 HttpResponseMessage
【发布时间】:2012-12-31 15:07:37
【问题描述】:

当使用HttpClientHttpResponseMessage 时,WebResponse.IsFromCache 的等价物是什么?

响应中是否有一些我可以查看的 HTTP 标头?

【问题讨论】:

    标签: c# .net http dotnet-httpclient


    【解决方案1】:

    仅供参考:Windows.Web.Http HttpClient(针对 Windows 8.1 应用程序开发的类似 API)确实包含一个 HttpResponseMessage.Source 字段,该字段指定结果的来源(常见值为“缓存”和“网络”)。

    Windows.Web.Http 类可用于 C# 和其他 .NET 语言、C++ 和 JavaScript(当作为 WwaHost 应用程序运行时,如来自 Windows 应用商店)。

    【讨论】:

      【解决方案2】:

      我能问一下你想达到什么目标吗?是否试图避免缓存?

      询问的原因是我查看了HttpClient 的源代码(特别是HttpClientHandler)和HttpWebResponse 的源代码,我不相信您可以从标题中获得这些信息。

      HttpClient/HttpClientHandler 在内部使用 HttpWebResponse,但它公开HttpWebResponse的所有属性:

      private HttpResponseMessage CreateResponseMessage(HttpWebResponse webResponse, HttpRequestMessage request)
      {
            HttpResponseMessage httpResponseMessage = new HttpResponseMessage(webResponse.StatusCode);
            httpResponseMessage.ReasonPhrase = webResponse.StatusDescription;
            httpResponseMessage.Version = webResponse.ProtocolVersion;
            httpResponseMessage.RequestMessage = request;
            httpResponseMessage.Content = (HttpContent) new StreamContent((Stream) new HttpClientHandler.WebExceptionWrapperStream(webResponse.GetResponseStream()));
      
            //this line doesnt exist, would be nice
            httpResponseMessage.IsFromCache = webResponse.IsFromCache;// <-- MISSING!
           ...
       }
      

      所以你的选择在我看来是这样的:

      a) 查看HttpWebRequest 的源代码以确定IsFromCache 的逻辑并以某种方式将其改造成HttpClient(这甚至可能是不可能的,取决于逻辑的实际作用/需要)

      b) 要求 ASP.NET 团队将此属性包含在 HttpResponseMessage 中。要么直接作为财产,要么他们可以“保留”HttpWebResponse

      这些选项都不是很抱歉,因此我最初的问题是,你想达到什么目的?

      【讨论】:

      • 对,我意识到它不见了。而且我还查看了 HttpClient 源代码和 HttpWebRequest,并且 IsFromCache 的源代码似乎很模糊,因此逆向工程似乎很难或不可能。我需要它,因为当从缓存返回 HTTP 错误时,我需要使用缓存重新加载参数再次尝试,以确保如果错误已在服务器上得到纠正,客户端会注意到它。
      【解决方案3】:

      我最近也一直在为这种情况而苦苦挣扎。

      我需要的是一个集成测试来验证:

      • 对新创建资源的响应具有服务器设置的正确标头。
      • 从客户端缓存中满足了对该资源的后续请求。
      • 现有资源的响应也具有服务器设置的正确标头。

      我最终做的是双重检查:

      用于检查初始响应的非缓存 HttpClient:

      new WebRequestHandler
      {
        AllowAutoRedirect = true,
        UseCookies = true,
        CookieContainer = new CookieContainer(),
        CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.Refresh)
      };
      
      var client = new HttpClient(handler)
      

      和第二个 HTTP 客户端检查客户端缓存:

      new WebRequestHandler
      {
        AllowAutoRedirect = true,
        UseCookies = true,
        CookieContainer = new CookieContainer(),
        CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.Default)
      };
      
      var client = new HttpClient(handler)
      

      为了验证响应消息的来源,我比较了第 1 步和第 2 步中的 HttpResponseMessage.Headers.Date 值(如果响应来自客户端缓存,这将是相同的)。对于我的第三步,我可以重用第一步中的客户端并将任意字符串附加到 URL。

      免责声明:这适用于 .NET Framework 4.7,并忽略了有关 HttpClient 使用的最佳实践,但在我的测试套件中似乎对我有用。像上面提到的那样的显式属性会更好,但似乎不可用。由于这里的最后一个回复已经有几年了,可能有更好的方法来处理这个问题,但我想不出一个。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-07
        • 1970-01-01
        • 2017-08-02
        • 2010-11-21
        • 1970-01-01
        相关资源
        最近更新 更多