`

HttpClient .NET4.5 使用方法

 
阅读更多

简介

本文的主要参考资料:C# 5.0 in  a nutshell   ,由于我的英文能力有限,算是读书笔记。需要此书的可以留邮箱地址。以下是正文:

HttpClient是.NET4.5提供的一个实现了http传输协议的类,该类可以说分装了HttpWebRequest和HttpWebResponse,它可以说是WebClient的精简升级版,适用于新的Metro-Style  App以及原生的异步模式,在Metro-Style App中已不能使用原来的WebClient了,所以你可以把它看成是一个替代的类。它与WebClient相比,有几个特点:

  1. 一个单一的HttpClient实例,便可以被并发地使用,而不需重新生成实例,换句话说,它是线程安全,而且一次生成,N次使用,中间就少了很多重复的设置过程。
  2. HttpClient可以让你实现并插入自己的消息处理,这对于记录以及单元测试非常有好处。
  3. HttpClient拥有丰富和扩展性强的Headers和Content类型系统。
  4. 当然,HttpClient并非可以完全替代WebClient,因为后者还包括了处理FTP协议的能力,应该说HttpClient主要替代的是在Metro-Style App中WebClient实现Http协议的能力。

使用快速入门
使用HttpClient最简单的方法,便是,先实例化一个HttpClient,然后在”Get* “系列方法中传入一个URI地址,如:

 

string html = await new HttpClient().GetStringAsync ("http://linqpad.net");
 

 当然,还有GetByteArrayAsync 和GetStreamAsync方法,这些方法很简单。而特点1的代码体现如下:

 

var client = new HttpClient();
var task1 = client.GetStringAsync ("http://www.linqpad.net");
var task2 = client.GetStringAsync ("http://www.albahari.com");
Console.WriteLine (await task1);
Console.WriteLine (await task2);
 

 HttpClient有一个Timeout属性(作用如其名字)和一个BaseAddress属性(可以作为URI的头部分)。

但是HttpClient只是简单的一个外壳而已,具体的配置类被抽象出成了一个接口,叫做HttpMessageHandler,其中,.NET为我们实现了一个具体的类,叫做HttpClientHandler(实现了HttpMessageHandler接口),使用代码如下:

 

var handler = new HttpClientHandler { UseProxy = false };
var client = new HttpClient (handler);
...
 

 也就是HttpClient有个接收该接口的重载版本,这个例子中,我们使得此次的Http操作不能用代理来进行。该抽象接口在后续介绍。

GetAsync和response messages(即代表http返回报文的一个类)

以上的GetStringAsync, GetByteArrayAsync, 和 GetStreamAsync都是HttpClient的GetAsync方法的简化版本(也就是说调用者更明确地想将返回的结果具体化,而非只是一个response message),若使用底层的GetAsync,那么代码参考如下:

 

var client = new HttpClient();
// The GetAsync method also accepts a CancellationToken.
HttpResponseMessage response = await client.GetAsync ("http://...");
response.EnsureSuccessStatusCode();
string html = await response.Content.ReadAsStringAsync();
 

HttpResponseMessage对象就是代表了一个Http请求从服务器返回的“报文”,HttpResponseMessage暴露了属性用于访问“报文”中的Headers信息,它是一个HttpResponseHeaders类型的属性(继承自发送和返回Headers共享的HttpHeaders),具体有哪些可以参考API文档。

。HttpResponseMessage当然还有典型的“返回状态码”属性,即StatusCode,这概念了解一下Http协议便可以知道,当然一般它的值是200的时候,说明是返回正常,但你可以用属性IsSuccessStatusCode来指示Http响应是否成功。

不像WebClient,在使用HttpClient时,若StatusCode返回的是非成功的,比如是404(not found),它是不会抛出异常,若你想让它抛出,则需要调用HttpResponseMessage对象的 EnsureSuccessStatusCode方法,然后再去对Content进行处理。Content是一个HttpContent 类型,代表的是Http协议返回报文中的Body部分,它是承载从服务器返回的具体的内容的,算是最重要的payload,很多时候,我们只要把这部分的东东解析成一个XML文档即可。      HttpResponseMessage有个CopyToAsync的方法将承载的内容写到另外一个Stream中,比如将它输出到一个文件流中,代码如下:

 

using (var fileStream = File.Create ("linqpad.html"))
await response.Content.CopyToAsync (fileStream);
 

 最后,GetAsync是Http协议的四个方法之一(分别是GET,POST,PUT和DELETE,在HttpClient都已经有对应的方法了,分别是GetAsync,PostAsync,PutAsync和DeleteAsync)。其实占用流量最多是GET,其次是POST。

SendAsync 和request messages(Http请求报文)

上一节中描述的HttpClient的四大方法,其实是对应到的是一个SendAsync方法,因为对于底层来说,你把对应的协议请求报文准备好,然后统一执行一个发送动作将报文发送出去。而SendAsync方法接收的参数就是一个代表“请求报文”的Request,参考代码如下:

 

var client = new HttpClient();
var request = new HttpRequestMessage (HttpMethod.Get, "http://...");
HttpResponseMessage response = await client.SendAsync (request);
response.EnsureSuccessStatusCode();
...
 

 而以上这段稍微复杂的代码等效于快速入门那一节的那两句代码。自定义一个HttpRequestMessage对象,意味着,你要自己构建一些Header,以及在Content中传入Post需要的负载信息。

Uploading data and HttpContent

在使用Post方法时,往往是为了给服务器端发送一段数据(比如一个XML,一张图片),而这段数据便可以通过留的形式放在HttpRequestMessage的Content中,它和HttpResponseMessage中的Content一样,都是HttpContent类型。.NET给我们提供了4个继承自HttpContet的类,用以将传输数据,如下:


  • ByteArrayContent
  • StringContent
  • FormUrlEncodedContent
  • StreamContent


参考代码如下:

 

var client = new HttpClient (new HttpClientHandler { UseProxy = false });
var request = new HttpRequestMessage (
HttpMethod.Post, "http://www.albahari.com/EchoPost.aspx");
request.Content = new StringContent ("This is a test");
HttpResponseMessage response = await client.SendAsync (request);
response.EnsureSuccessStatusCode();
Console.WriteLine (await response.Content.ReadAsStringAsync());
 


 其中“This is a test”就是你要传给服务器的数据,当然,这没啥意义。

HttpMessageHandler

之前提到过的,大多数自定义的请求属性是定义在HttpClientHandler(.net提供的,实现了HttpMessageHandler)上,而不是在HttpClient上。以下是HttpMessageHandler的部分:

 

public abstract class HttpMessageHandler : IDisposable
{
protected internal abstract Task<HttpResponseMessage> SendAsync
(HttpRequestMessage request, CancellationToken cancellationToken);
public void Dispose();
protected virtual void Dispose (bool disposing);
}
 


 你会突然发现,这里面也有一个SendAsync方法,那么其实,HttpClient的SendAsync方法就是调用HttpMessageHandler的这个方法的。

   Unit testing and mocking(使用自定义HttpMessageHandler来单元测试和模拟

代码1,自定义的HttpMessageHandler,即MockHandler:

 

class MockHandler : HttpMessageHandler
{
Func <HttpRequestMessage, HttpResponseMessage> _responseGenerator;
public MockHandler
(Func <HttpRequestMessage, HttpResponseMessage> responseGenerator)
{
_responseGenerator = responseGenerator;
}
protected override Task <HttpResponseMessage> SendAsync
(HttpRequestMessage request, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var response = _responseGenerator (request);
response.RequestMessage = request;
return Task.FromResult (response);
}
}
 


 代码2,在单元测试中使用MockHandler

 

var mocker = new MockHandler (request =>
new HttpResponseMessage (HttpStatusCode.OK)
{
Content = new StringContent ("You asked for " + request.RequestUri)
});
var client = new HttpClient (mocker);
var response = await client.GetAsync ("http://www.linqpad.net");
string result = await response.Content.ReadAsStringAsync();
Assert.AreEqual ("You asked for http://www.linqpad.net/", result);
 


使用 DelegatingHandler实现“职责链模式”

DelegatingHandler是.NET提供的,继承自HttpResponseMessage,用来实现职责链模式的类,使用方法如下:

 

class LoggingHandler : DelegatingHandler
{
public LoggingHandler (HttpMessageHandler nextHandler)
{
InnerHandler = nextHandler;
}
protected async override Task <HttpResponseMessage> SendAsync
(HttpRequestMessage request, CancellationToken cancellationToken)
{
Console.WriteLine ("Requesting: " + request.RequestUri);
var response = await base.SendAsync (request, cancellationToken);
Console.WriteLine ("Got response: " + response.StatusCode);
return response;
}
}
 

 其中,DelegatingHandler定义了一个InnerHandler属性(根据设计模式也能知道,它也是HttpMessageHandler类型),用于内部使用,也就是base.SendAsync调用时,会调用InnerHandler的SendAsync。那么我们只需要进行一些自己需要的操作即可,这是关于设计模式的,不比多说。

 

 

分享到:
评论

相关推荐

    C# httpclient demo

    3. **.NET4.5**:这是微软.NET Framework的一个版本,包含了大量的API和改进,其中就包括了HttpClient类。 4. **HttpClient**:是.NET Framework 4.5引入的新组件,用于执行HTTP请求,提供了更简单、更直观的API,...

    HttpClient4.5 实现https忽略SSL证书验证

    使用HttpClient4.5实现https请求忽略SSL证书验证工具类

    httpClient4.5配置SSL绕过https证书,httpClient过时替代方法-附件资源

    httpClient4.5配置SSL绕过https证书,httpClient过时替代方法-附件资源

    httpclient4.5 绕过ssl认证文件访问

    在IT行业中,网络通信是至关重要的,特别是在进行Web服务交互时...通过学习上述内容,你将能够使用HTTPClient 4.5成功访问那些需要绕过SSL认证的HTTPS网站。在实际项目中,一定要谨慎处理这种情况,确保数据的安全性。

    CacheCow:在.NET Core和4.5.2+中为客户端和服务器实现HTTP缓存的实现

    CacheCow.Client进行了一些更改,这些更改可能会或可能不会破坏您的代码(取决于您是否使用过.NET 4.5软件包),其中包括: 现在所有接口都完全异步 许多高速缓存存储不再维护和可用,包括:MongoDb,Memcached,...

    .net本地模拟POST请求

    2. 使用`HttpClient`类(自.NET Framework 4.5开始引入): - 创建一个`HttpClient`实例,然后调用`PostAsync`方法,传入URL和表示POST数据的`HttpContent`对象。 - `PostAsync`返回一个`Task...

    HttpClient4.5-API-部分翻译

    由网上博客整理而成的PDF。该PDF是关于HttpClient4.5-API进行部分翻译,我觉得翻译的很不错,就整理下来留存一份。原博客地址:http://blog.csdn.net/u011179993/article/details/47123727 侵删。谢谢。

    .net4.5使用async和await异步编程实例

    随着.NET框架4.5及更高版本,许多系统库和第三方库都开始支持异步操作,例如`HttpClient`,它提供了异步的HTTP请求方法,如`GetAsync`和`PostAsync`。这些异步方法使得在处理网络通信时可以避免阻塞主线程,提高用户...

    对于C#(HttpClient)方式网络请求的封装

    HttpClient是.NET Framework和.NET Core中用于发送HTTP请求的标准库,它提供了异步和同步的API,适用于各种网络操作,如GET、POST、PUT等。 描述中的链接指向了一个具体的博客文章,该文章详细解释了如何在C#项目中...

    支付宝接口(.net2.0)

    在.NET 2.0中,可以使用`System.Net.WebClient`或`System.Net.Http.HttpClient`类来发送HTTP POST请求,将必要的参数(如商品信息、订单号、金额等)传递给支付宝服务器。 5. **异步处理与回调**:在用户完成支付后...

    httpclient所需jar包

    本文将深入探讨HTTPClient库以及如何在不使用Maven的情况下将其集成到项目中。 首先,我们来了解HTTPClient的核心概念。Apache HttpClient是Apache软件基金会的一个开源项目,它实现了多种HTTP协议标准,包括...

    C#.NET各种解密方法,请求方法

    3. `HttpClient`(自.NET Framework 4.5起):这是现代、异步支持的网络请求库,更易于使用且性能更好。例如,你可以使用`HttpClient.GetAsync`或`PostAsync`方法发送GET和POST请求。 在网络请求中,证书转换也是一...

    .net 一般处理程序获取Http推送的包体Body

    实现了别的服务器通过Http协议接口推送到自己的服务器包体(body)接收代码的实现过程,我这里是用的.net的一般处理程序做的Http接口,调用时候无需定义参数,发布后访问文件全路径就可以获取对方传过来的包体全部...

    使用HttpClient必须的jar包

    7. **异步处理**:HttpClient 4.5以上版本提供了异步客户端API,可以并发处理多个请求,提高应用的并发性能。 8. **SSL/TLS支持**:HttpClient可以配置为使用HTTPS协议,需要`httpmime-x.x.x.jar`(处理MIME类型,...

    System.Net.Http.dll下载

    `HttpClient`是.NET Framework 4.5及更高版本引入的一个新组件,它是用于执行HTTP操作的首选API。相较于之前的`HttpWebRequest`,`HttpClient`设计更加面向对象,更易于使用,且性能更优。它支持异步操作,可以更好...

    System.Net.Http.Formatting各版本.zip

    在描述中提到的"System.Net.Http.Formatting各版本.zip"是一个包含不同版本的此组件的压缩包,目的是为了解决在使用`HttpClient`类时可能遇到的特定问题,尤其是关于`PostAsJsonAsync`方法的不支持。 `HttpClient`...

    .NET HTTP 请求服务接口

    HttpClient是.NET Framework 4.5及更高版本引入的类,它提供了更简洁、更直观的API来发送HTTP请求。HttpClient不仅易于使用,而且支持异步操作,更适合现代的多线程和高并发环境。HttpClient的核心方法包括GetAsync...

    C#HTTPclient 实例应用

    这个类是.NET Framework 4.5引入的,随后也在.NET Core中得到支持,成为了处理网络通信的标准方式。在本文中,我们将深入探讨`HttpClient`的实例应用,以及如何使用它来实现各种HTTP操作。 ### 1. `HttpClient`的...

    如何从REST方法检索标量值

    以上就是在C# .NET 4.5中使用ASP.NET技术从REST方法检索标量值的详细过程。通过理解REST的工作原理和HttpClient类的功能,开发者可以轻松地与各种REST服务进行交互,获取和处理返回的数据。在实际项目中,可能还需要...

    RestEase:适用于.NET Standard 1.1和.NET Framework 4.5及更高版本的易于使用的类型安全REST API客户端库,该库很简单且可自定义。 灵感来自改装

    轻松自在 RestEase是适用于.NET Framework 4.5和更高版本以及.NET Platform Standard 1.1和更高版本的,类型安全的REST API客户端库,旨在简化与远程REST端点的交互,而不会增加不必要的复杂性。 要使用它,您需要...

Global site tag (gtag.js) - Google Analytics