如何选择 WebClient,HttpClient,HttpWebRequest
当我们在用 .NET 调用 RestAPI 时通常有三种选择,分别为:WebClient, HttpWebRequest,HttpClient,这篇文章我们将会讨论如何使用这三种方式去调用 RestAPI,我还会提供相应的代码案例来帮助你更好的理解这三者的概念和使用方式,简单来说:
- HttpWebRequest是一种相对底层的处理 Http request/response 的方式。
- WebClient提供了对 HttpWebRequest 的高层封装,来简化使用者的调用。
- HttpClient是一种新的处理 Http request/response 工具包,具有更高的性能。
接下来我们讨论一下抽象类 WebRequest。
WebRequest
WebRequest 是一种基于特定的 http 实现, 它是一个抽象类, 所以在处理 Reqeust 请求时底层会根据传进来的 url 生成相应的子类,如:HttpWebRequest 或 FileWebRequest ,下面的代码展示了如何使用 WebRequest。
WebRequest webRequest = WebRequest.Create(uri);
webRequest.Credentials = CredentialCache.DefaultCredentials;
webRequest.Method ="GET";
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
WebRequest 是 .NET Framework 中第一个用来处理 Http 请求的类,在处理 Http请求和响应 方面给调用者提供了诸多的灵活性,你还可以使用这个类来存取 headers, cookies, protocols 和 timeouts 等等,下面的代码展示了其实现子类 HttpWebRequest 是如何使用的。
HttpWebRequest http = HttpWebRequest)WebRequest.Create(“http://localhost:8900/api/default”);
WebResponse response = http.GetResponse();
MemoryStream memoryStream = response.GetResponseStream();
StreamReader streamReader = new StreamReader(memoryStream);
string data = streamReader.ReadToEnd();
WebClient
WebClient 是 HttpWebRequest 的高层封装,它给调用者提供了更便捷的使用方式,理所当然做出的牺牲就是 WebClient 的性能略逊于 HttpWebRequest,如果你的业务场景只是简单访问第三方的 Http Service,那么我建议你使用 WebClient ,同理如果你有更多的精细化配置则使用 HttpWebRequest,下面的代码展示了如何使用 WebClient 。
string data = null;
using (var webClient = new WebClient())
{
    data = webClient.DownloadString(url);
}
HttpClient
HttpClient 是在 .NET Framework 4.5 中被引入的,如果你的项目是基于 .NET 4.5 以上版本,除一些特定的原因之外,建议你优先使用 HttpClient,本质上来说,HttpClient 作为后来之物,它吸取了 HttpWebRequest 的灵活性及 WebClient 的便捷性,所以说 和 可兼得。
HttpWebRequest 在 request/response 对象上提供了非常精细化的配置,同时你也要注意 HttpClient 的出现并不是为了取代 WebClient,言外之意就是 HttpClient 也有缺点,比如说:不能提供 进度处理 和 URI 定制,不支持 FTP 等等,HttpClient 的优点也有很多,它所有关于 IO 操作的方法都是异步的,当然有特殊原因的话也可以使用同步方式,下面的代码展示了如何使用 HttpClient。
public async Task<Author> GetAuthorsAsync(string uri)
{
    Author author = null;
    HttpResponseMessage response = await client.GetAsync(uri);
    if (response.IsSuccessStatusCode)
    {
        author = await response.Content.ReadAsAsync<Author>();
    }
    return author;
}
值得注意的是当 response 出现错误时,默认情况下 HttpClient 并不会抛出异常,如果你一定要求 HttpClient 在这种情况下抛出异常,可更改 IsSuccessStatusCode = false 来改变这种默认行为,做法就是调用 response.EnsureSuccessStatusCode();。
public async Task<Author> GetAuthorsAsync(string uri)
{
    Author author = null;
    HttpResponseMessage response = await client.GetAsync(uri);
    response.EnsureSuccessStatusCode();
    if (response.IsSuccessStatusCode)
    {
        author = await response.Content.ReadAsAsync<Author>();
    }
    return author;
}
在项目开发中,推荐的做法是保持 HttpClient 的单例化,如果不这么做的话,每次 Request 请求实例化一次 HttpClient ,那么大量的请求必将你的 socket 耗尽并抛出 SocketException 异常。
更多精彩,欢迎订阅

译文链接:https://www.infoworld.com/article/3198673/when-to-use-webclient-vs-httpclient-vs-httpwebrequest.html
如何选择 WebClient,HttpClient,HttpWebRequest的更多相关文章
- WebClient, HttpClient, HttpWebRequest ,RestSharp之间的区别与抉择
		NETCore提供了三种不同类型用于生产的REST API: HttpWebRequest;WebClient;HttpClient,开源社区创建了另一个名为RestSharp的库.如此多的http库 ... 
- WebRequest/HttpWebRequest/HttpRequest/WebClient/HttpClient的区别
		1.WebRequest和HttpWebRequest WebRequest 的命名空间是: System.Net ,它是HttpWebRequest的抽象父类(还有其他子类如FileWebReque ... 
- C#的提交表单方式主要有两种WebClient与HttpWebRequest
		根据黄聪:C#模拟网站页面POST数据提交表单(转) using System; using System.Collections.Generic; using System.IO; using Sy ... 
- 使用WebClient與HttpWebRequest的差異
		在<Windows Phone 7-下載檔案至Isolated Storage>提到了透過WebClient的功能將網站上的檔案下載至 WP7的Isoated Storage之中.但實際的 ... 
- webrequest HttpWebRequest webclient/HttpClient
		webrequest(abstract类,不可直接用) <--- (继承)---- HttpWebRequest(更好的控制请求) <--- (继承)---- webclient (简单快 ... 
- [解决WebClient或HttpWebRequest首次连接缓慢问题]
		[编程环境]Visual Studio 2010, NET4.0 [开发语言]C#, 理论上VB.NET等依赖.NET Framework框架的语言均受此影响 [问题描述] 使用HttpWebRequ ... 
- [转]解决WebClient或HttpWebRequest首次连接缓慢问题
		http://blog.csdn.net/rrrfff/article/details/6170653?reload 设置代理为空: <?xml version="1.0"? ... 
- 使用C# HttpWebRequest进行多线程网页提交。Async httpclient/HttpWebRequest实现批量任务的发布及异步提交和超时取消
		使用线程池并发处理request请求及错误重试,使用委托处理UI界面输出. http://www.cnblogs.com/Charltsing/p/httpwebrequest.html for (i ... 
- 网络编程之webclient和httpwebrequest的使用
		(1)Lambda表达式 “Lambda表达式”是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式树类型. 所有 Lambda 表达式都使用 Lambda 运算符 =>,该运算符 ... 
随机推荐
- LSTM - 长短期记忆网络
			循环神经网络(RNN) 人们不是每一秒都从头开始思考,就像你阅读本文时,不会从头去重新学习一个文字,人类的思维是有持续性的.传统的卷积神经网络没有记忆,不能解决这一个问题,循环神经网络(Recurre ... 
- cmder设置方法
			一.添加鼠标右键 Cmder.exe /REGISTER ALL 二.添加系统环境变量 我的电脑 > 右键属性 > 高级系统设置 > 环境变量 > 系统变量,在path中添加 ... 
- XCTF攻防世界web进阶练习—mfw
			XCTF攻防世界web进阶练习-mfw题目为mfw,没有任何提示.直接打开题目,是一个网站 大概浏览一下其中的内容,看到其中url变化其实只是get的参数的变化查看它的源码,看到有一个?page=fl ... 
- Redis in Action : Redis  实战学习笔记
			1 1 1 Redis in Action : Redis 实战学习笔记 1 http://redis.io/ https://github.com/antirez/redis https://ww ... 
- style element & web components
			style element & web components style.textContent style.setContent bug style.textContent const st ... 
- javascript algorithm visualization
			javascript algorithm visualization javascript算法可视化 https://algorithm-visualizer.org https://github.c ... 
- classnames & React & taro
			classnames & React & taro classnames https://www.npmjs.com/package/classnames demo https://g ... 
- Taro Advanced
			Taro Advanced aro 代码与小程序代码混写 https://nervjs.github.io/taro/docs/hybrid.html https://github.com/NervJ ... 
- js in depth: Object & Function & prototype & __proto__ & constructor & classes inherit
			js in depth: Object & Function & prototype & proto & constructor & classes inher ... 
- rxjs 常用的subject
			api列表 Subject Subject是可观察的一种特殊类型,它允许将值多播到许多观察者 import {Subject} from 'rxjs'; const l = console.log; ... 
