当我们需要在 .NET 中调用 RestAPI 的时候我们可以使用 HttpWebRequest WebClient HttpClient,我来描述一下这三种的使用以及区别。
WebRequest
首先先讲一下 WebRequest ,WebRequest 是一个抽象类, 是一种基于特定的 http 实现,在处理 Request 时底层会根据传入的 url 生成相应的子类.如: HttpWebRequest FileWebRequest. HttpWebRequest 是一种相对底层的处理 Http request/response 的方式。我们可以通过此类来存取 headers cookies 等信息.
在获取响应时指定为 HttpWebResponse
1WebRequest webRequest = WebRequest.Create(uri);2webRequest.Method = "GET";3HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();在创建时指定为 HttpWebRequest
1HttpWebRequest http = (HttpWebRequest)WebRequest.Create("http://baidu.com");2http.Method = "GET";3WebResponse response = http.GetResponse();读取响应内容
1Stream stream = response.GetResponseStream();2StreamReader streamReader = new StreamReader(stream);3string data = streamReader.ReadToEnd();WebClient
WebClient 提供了对 HttpWebRequest 的高层封装,用来简化调用。在不需要精细化配置的情况下可以进行使用。比方说使用它来设置请求时的 Cookie 就需要以字符串的形式直接写入 Headers 当中,而不能操作 Cookie 类型的对象.
1using (var webClient = new WebClient())2{3 string data = webClient.DownloadString("http://baidu.com");4}写入 Cookie
1using (WebClient webClient = new WebClient())2{3 webClient.Encoding = Encoding.GetEncoding("utf-8");4 webClient.Headers.Add("Content-Type", "application/json");5 webClient.Headers.Add(HttpRequestHeader.Cookie, $@"{CookieName}={CookieValue}");6 byte[] responseData = webClient.UploadData(url, "POST", postData);7 re = JsonConvert.DeserializeObject<JObject>(Encoding.UTF8.GetString(responseData));8}HttpClient
HttpClient 是一种新的处理 Http request/response 工具包,具有更高的性能。他是在 .NET Framework 4.5 中被引入的,它吸取了 HttpWebRequest 的灵活性及 WebClient 的便捷性,它所有关于 IO 操作的方法都是异步的。
1HttpClient client = new HttpClient();2HttpResponseMessage response = await client.GetAsync("http://baidu.com");3if (response.IsSuccessStatusCode)4{5 string data = await response.Content.ReadAsStringAsync();6}默认情况下 HttpClient 不会自动抛出异常, 通过调用 response.EnsureSuccessStatusCode(); 可以在请求失败的时候抛出异常,当有需要的时候可以判断 response.StatusCode 的值手动抛出异常。
另外每次 Request 就实例化一次 HttpClient,大量的请求必会将 socket 耗尽抛出 SocketException 异常。正确的使用方法应该是使用单例模式或工厂类来创建 HttpClient 对象。
在 ASP.NET Core 中我们可以下列方式获取 HttpClient 对象。
1// 添加服务2services.AddHttpClient();3
4...5
6// 在构造函数中注入 IHttpClientFactory 类7private readonly IHttpClientFactory httpClientFactory;8
9public TestController(IHttpClientFactory httpClientFactory)10{11 this.httpClientFactory = httpClientFactory;12}13
14...15
7 collapsed lines
16// 使用 IHttpClientFactory 工厂获取 HttpClient 对象17HttpClient httpClient = httpClientFactory.CreateClient("RequertBaidu");18HttpResponseMessage httpResponse = await httpClient.GetAsync("http://baidu.com");19if (httpResponse.IsSuccessStatusCode)20{21 string data = await httpResponse.Content.ReadAsStringAsync();22}