【问题标题】:How to Replace WebClient with HttpClient?如何用 HttpClient 替换 WebClient?
【发布时间】:2023-09-22 06:18:01
【问题描述】:

我的 asp.net mvc Web 应用程序中有以下 WebClient:

using (WebClient wc = new WebClient()) // call the Third Party API to get the account id 
{
     string url = currentURL + "resources/" + ResourceID + "/accounts?AUTHTOKEN=" + pmtoken;
     var json = await wc.DownloadStringTaskAsync(url);
 }

那么任何人都可以建议我如何将它从 WebClient 更改为 HttpClient?

【问题讨论】:

  • 现在所有酷孩子都在使用 HttpClient。这是一个围绕 WebRequest 的包装器,提供了一个更容易使用的模型。
  • @Ananke 好的,你能告诉我如何将 WebClient 更改为 HttpClient 吗?

标签: .net webrequest webclient


【解决方案1】:

可以编写如下代码:

string url = 'some url';

// best practice to create one HttpClient per Application and inject it
HttpClient client = new HttpClient();

using (HttpResponseMessage response = client.GetAsync(url).Result)
{
    using (HttpContent content = response.Content)
    {
         var json = content.ReadAsStringAsync().Result;
    }
}

更新 1

如果您想用await 关键字替换对Result 属性的调用,那么这是可能的,但是您必须将此代码放入标记为async 的方法中,如下所示

public async Task AsyncMethod()
{
    string url = 'some url';

    // best practice to create one HttpClient per Application and inject it
    HttpClient client = new HttpClient();

    using (HttpResponseMessage response = await client.GetAsync(url))
    {
        using (HttpContent content = response.Content)
        {
           var json = await content.ReadAsStringAsync();
        }
     }
}

如果您错过了方法中的 async 关键字,您可能会收到如下所示的编译时错误

“await”运算符只能在异步方法中使用。考虑使用“async”修饰符标记此方法并将其返回类型更改为“Task”。

更新 2

回答您关于将“WebClient”转换为“WebRequest”的原始问题,这是您可以使用的代码,......但微软(和我)建议您使用第一种方法(通过使用 HttpClient)。

string url = currentURL + "resources/" + ResourceID + "/accounts?AUTHTOKEN=" + pmtoken;

HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.Method = "GET";

using (WebResponse response = httpWebRequest.GetResponse())
{
     HttpWebResponse httpResponse = response as HttpWebResponse;
     using (StreamReader reader = new StreamReader(httpResponse.GetResponseStream()))
     {
         var json = reader.ReadToEnd();
     }
}

如果你使用 C# 8 及以上版本,那么你可以编写非常优雅的代码

public async Task AsyncMethod()
{
    string url = 'some url';

    // best practice to create one HttpClient per Application and inject it
    HttpClient client = new HttpClient();

    using HttpResponseMessage response = await client.GetAsync(url);
    using HttpContent content = response.Content;
    var json = await content.ReadAsStringAsync();
}   // dispose will be called here, when you exit of the method, be aware of that

更新 3

要知道为什么HttpClientWebRequestWebClient 更推荐,您可以参考以下链接。

Deciding between HttpClient and WebClient

http://www.diogonunes.com/blog/webclient-vs-httpclient-vs-httpwebrequest/

HttpClient vs HttpWebRequest

What difference is there between WebClient and HTTPWebRequest classes in .NET?

http://blogs.msdn.com/b/henrikn/archive/2012/02/11/httpclient-is-here.aspx

【讨论】:

  • 感谢您的回复,但是如果我在您的代码中将 .Result 替换为 await 会有什么问题吗?
  • @johnG 请查看更新的答案以处理“等待”而不是“结果”属性。
  • @johnG 我还为“WebRequest”类添加了更新。
  • 感谢回复,但是为什么推荐使用HttpClient,我没明白你的意思..谢谢...
  • HttpClient 包装在using 块中是不好的。请不要这样做。有关原因的详细说明,请参阅下面的链接。长话短说,HttpClient 被设计为在整个应用程序中用作单个实例。它为您处理打开和关闭套接字。通过将其包装在 using 块中,它会在之后被处理,并且不会像预期的那样关闭套接字。一旦达到每秒请求的某个阈值,这可能会导致系统用完套接字。 aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong