如何使用HttpClient确定HttpResponseMessage是否从缓存中获取

6
当使用HttpClient和HttpResponseMessage时,WebResponse.IsFromCache的等效内容是什么?
我能否查看响应中的某个HTTP头?
3个回答

2

请注意:Windows.Web.Http HttpClient(一个类似的API,面向Windows 8.1应用程序开发)包括一个HttpResponseMessage.Source字段,指定结果来自何处(常见值为“cache”和“network”)。

Windows.Web.Http类可从C#和其他.NET语言,从C ++以及从JavaScript(在像从Windows应用商店运行的WwaHost应用程序中运行时)中使用。


1

请问您想要实现什么目标?是想避免缓存吗?

我之所以这样问,是因为我查看了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

很抱歉,这两个选项都不是很好,这也是我最初提出问题的原因,你想要实现什么目标?


1
是的,我意识到它确实缺失了。我也查看了HttpClient源代码、HttpWebRequest以及IsFromCache的源代码,但是它们都非常混淆,因此反向工程似乎很困难甚至不可能。我需要它,因为当从缓存返回HTTP错误时,我需要使用缓存重新加载参数再次尝试,以确保如果服务器上的错误已经被纠正,客户端将会注意到它。 - Andrew Arnott

1

最近我也一直在应对这种情况。

我需要进行集成测试以验证:

  • 服务器设置的响应头正确地响应了新创建资源的请求。
  • 客户端缓存中已存在的资源的后续请求得到了满足。
  • 服务器同样正确地设置了现有资源的响应头。

我最终采取了双重检查的方法:

使用非缓存 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使用的最佳实践,但在我的测试套件中似乎起作用。像上面提到的显式属性会更可取,但似乎并不可用。由于这里的最后回复已经几年了,可能有更好的处理方式,但我想不出其他方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接