Esb*_*sen 2 .net caching asp.net-web-api dotnet-httpclient
我正在尝试启用 System.Net.HttpClient 的客户端缓存。我在http://localhost:83/api/test有一个端点,它需要 1 秒的时间来响应并将缓存标头发回。
如果我有这个代码
static async Task MainAsync()
{
var client = new HttpClient(new WebRequestHandler { CachePolicy = new HttpRequestCachePolicy() }) { BaseAddress = new Uri("http://localhost:83/api/") };
for (int i = 0; i < 20; i++)
{
var response = await client.GetAsync("test");
var res = await response.Content.ReadAsStringAsync();
Console.WriteLine(res);
}
}
Run Code Online (Sandbox Code Playgroud)
执行需要一秒钟。
如果我将相同的代码放入 api 控制器
static HttpClient client = new HttpClient(new WebRequestHandler {CachePolicy = new HttpRequestCachePolicy() }) { BaseAddress = new Uri("http://localhost:83/api/") };
public async Task<string> Get()
{
for (int i = 0; i < 20; i++)
{
var response = await client.GetAsync("test");
var res = await response.Content.ReadAsStringAsync();
}
return "ok";
}
Run Code Online (Sandbox Code Playgroud)
并将其托管在 IIS 中需要 20 秒才能响应。
我需要做什么才能从服务器应用程序启用客户端缓存?
可能您应该切换到 WinHTTP 并使用另一个 HTTP 缓存实现。
.NET Framework 使用两个 HTTP 客户端 API。一个由 WinINet 提供,另一个由 WinHTTP 提供。.NET Framework 默认使用 WinINet。但是 WinINet 是为在客户端应用程序中工作而开发的,它不应该在服务器环境中工作。MSDN 上Windows Internet页面的相关引用:
在适用的情况下
WinINet 不支持服务器实现。此外,不应从服务中使用它。对于服务器实现或服务,请使用Microsoft Windows HTTP 服务 (WinHTTP)。
因此,在您的 Web API 中,您需要使用 WinHTTP。我知道切换的唯一方法是WinHttpHandler从System.Net.Http.WinHttpHandler NuGet 包中使用。但是目前这个处理程序不使用 HTTP 缓存。它无法设置缓存策略,并且会忽略所有相关设置HttpClientHandler。请参阅如何通过 WinHttpHandler 和 HttpClient 使用 HTTP 缓存?GitHub 上的问题。
要解决此问题,您可以实现自己的缓存机制或使用现有的缓存机制,如CacheCow项目。它具有内置的内存存储和自己的DelagatingHandlerfor实现HttpClient。请注意,目前存在一些兼容性问题,在安装 System.Net.Http.WinHttpHandler 和 CacheCow.Clien NuGet 包之前,您需要从 Web API 项目中手动删除对 .NET Framework System.Net.Http 的引用。以下截取的代码演示了 CacheCow.Clien NuGet 包的用法WinHttpHandler和CachingHandler样例:
static HttpClient client = new HttpClient(new CachingHandler { InnerHandler = new WinHttpHandler() })
{
BaseAddress = new Uri("http://localhost:83/api/")
};
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请检查: