如何在 .NET 6 中用 HttpClient 替换过时的 WebClient
Posted
技术标签:
【中文标题】如何在 .NET 6 中用 HttpClient 替换过时的 WebClient【英文标题】:How to replace obsolete WebClient with HttpClient in .NET 6 【发布时间】:2021-12-01 13:27:05 【问题描述】:由于 WebClient 在 .NET 6 中已弃用,我想使用 WebClient 将以下代码转换为使用 HttpClient 调用 REST Web API 的等效代码:
using WebClient client = new();
client.Encoding = Encoding.UTF8;
client.Headers.Set(HttpRequestHeader.ContentType, "application/json");
client.Headers.Add("user_key", tokens[0]);
client.Headers.Add("Session_key", tokens[1]);
string json = JsonSerializer.Serialize(sms);
string serverResponse = client.UploadString(_baseUrl + "sms", "POST", json);
目前,我实现了以下解决方案:
HttpClient httpClient = _httpClientFactory.CreateClient();
HttpRequestMessage request = new(HttpMethod.Post, _baseUrl + "sms");
request.Headers.Add("user_key", tokens[0]);
request.Headers.Add("Session_key", tokens[1]);
string json = JsonSerializer.Serialize(sms);
request.Content = new StringContent(json, Encoding.UTF8, MediaTypeNames.Application.Json);
using HttpResponseMessage response = await httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
我认为上述解决方案是替换原始代码的最干净,最有效的方法。专家可以确认一下吗?
【问题讨论】:
【参考方案1】:看起来很简单:
HttpClient client = new()
BaseAddress = new Uri(_baseUrl)
;
using HttpRequestMessage request = new(HttpMethod.Post, "sms");
request.Headers.Add("user_key", tokens[0]);
request.Headers.Add("Session_key", tokens[1]);
string json = JsonSerializer.Serialize(sms);
request.Content = new StringContent(json, Encoding.UTF8)
Headers =
ContentType = new("application/json")
;
using HttpResponseMessage response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
string serverResponse = await response.Content.ReadAsStringAsync();
但是,您可能希望use the IHttpClientFactory
to create your HttpClient
instances,因为这提供了几个好处 - 特别是池化底层消息处理程序,以避免性能问题。
您可能还想考虑使用the PostAsJsonAsync
extension method,这可以简化此代码。
【讨论】:
但是与 WebClient 相比,没有简单的方法可以跟踪下载/上传进度,对吧?你需要做一些流 writeasync/readasync 逻辑。 @AyCe 看起来还不错:Progress bar with HttpClient 是的,我就是这个意思,我也看到了。问题是针对 Windows 运行时的,我还没有检查与 .NET Framework/Core/5.0/6.0 的兼容性如何。【参考方案2】:.Net 6 支持同步 Send()
这是一个简单的 GET:
using var httpClient = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://api.example.com/api/v1/get");
var response = httpClient.Send(request);
using var reader = new StreamReader(response.Content.ReadAsStream());
var responseBody = reader.ReadToEnd();
这是一个帖子:
var handler = new HttpClientHandler
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
;
var client = new HttpClient(handler)
BaseAddress = new Uri(_baseurl)
;
var webRequest = new HttpRequestMessage(HttpMethod.Post, "sms")
Content = new StringContent(json, Encoding.UTF8, "application/json")
;
webRequest.Headers.Add("user_key", tokens[0]);
webRequest.Headers.Add("Session_key", tokens[1]);
var response = client.Send(webRequest);
var reader = new StreamReader(response.Content.ReadAsStream());
var responseBody = reader.ReadToEnd();
【讨论】:
您的回答没有提供任何有价值的细节,说明为什么它比 OP 当前使用的解决方案更好。 这不是“更好” - 但它是人们可能想知道的新功能。以上是关于如何在 .NET 6 中用 HttpClient 替换过时的 WebClient的主要内容,如果未能解决你的问题,请参考以下文章
《ASP.NET Core 6框架揭秘》实例演示[17]:利用IHttpClientFactory工厂来创建HttpClient