1、HttpClient 类
(1)、HttpClient 类 用于发送HTTP 请求,接收请求的响应。
(2)、HttpClient 类 派生于 HttpMessageInvoker类,此基类负责执行 SendAsync(),SendAsync() 方法调用是异步的,可以编写一个完全异步的系统来调用Web服务。
2、实例
(1)、发出异步的Get 请求。
namespace InternetCommunicate { class Program { private const string baiduUrl = "http://www.baidu.com.cn"; private const string googleUrl = "http://www.google.com"; static void Main(string[] args) { } /// <summary> /// 异步调用Get方法 /// </summary> /// <returns></returns> public async Task GetDataSimpleAsync() { //实例化一个httpClient 对象,该对象是线程安全的, //client 对象可以处理多个请求,HttpClient 每个实例都维护自己的线程池, //HttpClient 实例之间的请求被隔离,调用Dispose方法释放资源。 using (var client = new HttpClient()) { //调用 GetAsync(),给他传递要调用的方法地址,把HTTP GET 请求发送给服务器, //GetAsync() 返回一个 HttpResponseMessage对象,包含 //(1)、标题 //(2)、状态 //(3)、内容 HttpResponseMessage response = await client.GetAsync(baiduUrl); //如果请求成功 if(response.IsSuccessStatusCode) { Console.WriteLine($"Response Status Code:{(int)response.StatusCode}" + $"{response.ReasonPhrase}"); //通过ReadAsStringAsync方法,把返回的内容检索为一个字符串。 string responseBodyAsText = await response.Content.ReadAsStringAsync(); Console.WriteLine($"Received payLoad of {responseBodyAsText.Length} characters"); Console.WriteLine(responseBodyAsText); Console.ReadLine(); } } } } }
(3)、传递httpheader(标题)
发出请求时,没有设置或改变任何标题,但HttpClient 的DefaultRequestHeaders 属性允许设置或改变标题,使用Add 方法可以给集合添加标题,设置标题和标题值后,会与HttpClient 实例发送的每个请求一起发送。
在本示例中,添加以json作为格式的标题值。代码如下:
/// <summary> /// 展示http 标题 /// </summary> /// <param name="title"></param> /// <param name="httpHeaders"></param> public static void ShowHeaders(string title,HttpHeaders httpHeaders) { foreach (var header in httpHeaders) { string value = string.Join(" ", header.Value); Console.WriteLine($"Header:{header.Key} Value:{value}"); } } /// <summary> /// 设置httpHeader 传递标题的信息 /// </summary> /// <returns></returns> public async Task GetDataWithHeadersAsync() { try { using(var client = new HttpClient()) { //添加作为json数据格式的标题值 client.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose"); //DefaultRequestHeaders 获取与每个请求一起发送的值 ShowHeaders("Request Headers:", client.DefaultRequestHeaders); //获取http 响应头的值 HttpResponseMessage response = await client.GetAsync(googleUrl); ShowHeaders("Response Headers:", response.Headers); } } catch (Exception ex) { throw ex; } }
(4)、用HttpMessageHandler自定义请求
创建一个派生于HttpClientHandler的类,重写SendAsync()方法,该方法需要返回一个Task,对于错误的情况,不需要调用异步方法,只用Task.FromResult返回即可。
public class SampleMessageHandler:HttpClientHandler { private string _message; public SampleMessageHandler(string message) { _message = message; } protected override Task<HttpResponseMessage> SendAsync( HttpRequestMessage request,CancellationToken cancellationToken) { if(_message == "error") { var response = new HttpResponseMessage(HttpStatusCode.BadRequest); return Task.FromResult<HttpResponseMessage>(response); } return base.SendAsync(request, cancellationToken); } } /// <summary> /// 用HttpMessageHandler自定义请求 /// </summary> /// <returns></returns> public static async Task GetDataWithMessageHandlerAsync() { //如果消息是error,把响应的状态码设置为bad request var client = new HttpClient(new SampleMessageHandler("error")); HttpResponseMessage responseMessage = await client.GetAsync(googleUrl); //etc }
(5)、使用SendAsync 创建HttpRequestMessage
使用SendAsync,可以对定义请求有更多的控制,重载HttpRequestMessage类的构造函数,传递HttpMethod的一个值,GetAsync方法用Get方式创建一个HTTP请求。
使用HttpMethod 不仅可以发送GET、POST、PUT和DELETE 请求,还可以发送HEAD、OPTIONS和Trace。
具体代码如下:
/// <summary> /// 使用SendAsync 创建HttpRequestMessage /// </summary> /// <returns></returns> private async Task GetDataAdvanceAsync() { using(var client = new HttpClient()) { var request = new HttpRequestMessage(HttpMethod.Get, googleUrl); HttpResponseMessage response = await client.SendAsync(request); } }