HttpClient学习记录
提供一个类,用于从 URI 标识的资源发送 HTTP 请求和接收 HTTP 响应。
注意事项
- HttpClient 旨在实例化一次,并在应用程序的整个生命周期内重复使用。如果为每个请求实例化 HttpClient 类,则重负载下可用的套接字数将耗尽。 这种耗尽将导致 SocketException 错误。
- 释放 HttpClient 实例会关闭打开的连接并取消所有挂起的请求。
- 每个 HttpClient 实例,都管理着自己的 TCP 连接池,该连接池可以在处理程序中配置连接池中 TCP 连接的数量,空闲的时间,生命周期
构造函数
HttpClient ()
HttpClient (HttpMessageHandler handler)
HttpClient (HttpMessageHandler handler, bool disposeHandler)
参数介绍:
HttpMessageHandler:HTTP 消息处理程序的基类。disposeHandler:表示是否在释放 HttpClient 实例时,同时释放 HttpMessageHandler ,如果想重用该处理程序就设置为 false,释放设置为 true
常用方法(目前默认的请求方法都是异步的,也是线程安全的)
Dispose ():释放产生的所有资源。
CancelPendingRequests ():取消 HttpClient 实例所有挂起的请求。
GetAsync (string url):以异步操作将 GET 请求发送给指定 URI。
PostAsync (String url, HttpContent content):以异步操作将 Post 请求发送给指定 URI。
SendAsync (HttpRequestMessage request):以异步操作发送 HTTP 请求。
HttpContent:表示请求体的积累HttpRequestMessage: 表示一条 HTTP 请求消息。
常用属性
BaseAddress:发送请求时使用的 Internet 资源的统一资源标识符 (URI) 的基址。例如:http://127.0.0.1:5500/ ,地址从协议名到端口号后面的一个斜杠,在发送请求时请求会将基址与请求的 url 组合起来以创建绝对 URI。
DefaultRequestHeaders:获取与每个请求一起发送的标题。设置默认的请求头,此属性上设置的标头不需要再次在请求消息上设置。
DefaultRequestVersion :获取或设置对此 HttpClient 实例发出的后续请求使用的默认 HTTP 版本,默认值 HttpVersion.Version11。
Timeout:为来自 HttpClient 实例的所有 HTTP 请求设置默认超时,默认是 100s,如果要设置为无限超时,可以将该属性设置为 TimeOut.InfiniteTimeSpan,建议不要设置为无限长
MaxResponseContentBufferSize :获取或设置读取响应内容时要缓冲的最大字节数,默认值为 2GB,返回的内容大小超过了该值就会抛出异常
一般情况下只需要设置 BaseAddress 的值即可
使用示例
static void Main(string[] args)
{
var client = new HttpClient()
{
BaseAddress = new Uri("http://localhost:5500/"),
DefaultRequestVersion = HttpVersion.Version11,
MaxResponseContentBufferSize = 1024 * 1024
};
client.DefaultRequestHeaders.Add("test", "123");
}
由 HttpClient 使用的默认消息处理程序,该类继承 HttpMessageHandler,.net core2.1 版本以上使用该类作为 HttpClient 的处理程序,还有其他的处理程序类,推荐使用该类
常用的属性
AutomaticDecompression :获取或设置处理程序用于自动解压缩 HTTP 内容响应的解压缩方法类型。默认是不开启解压缩的,建议不设置
ConnectTimeout :建立 tcp 连接超时时间,默认值是 TimeOut.InfiniteTimeSpan 无限长,建议不设置
MaxConnectionsPerServer :获取或设置允许向单个服务器连接的最大并行 TCP 连接数。(单个服务器指的是同一 域名),当请求数量超过该值,就会排队等待空闲的 tcp 连接,默认是 int.MaxValue,一般不用设置
PooledConnectionIdleTimeout :获取或设置池中连接的最大空闲时间。(发送请求后如果在最大空闲时间内没有再次发送该请求,那么 tcp 连接就会释放掉,该 tcp 连接就可以被其他请求使用) .net6 以上默认值为 1 分钟,.net6 以下为 2 分钟
PooledConnectionLifetime :每个 TCP 链接从创建开始存活的时间,默认是 TimeOut.InfiniteTimeSpan 无限长的,一般也不用设置这个参数;
UseCookies :获取或设置一个值,该值指示处理程序是否应使用 Cookie。上一个请求返回的 cookie,可能会随着下次请求发送出去。
然而,最佳的使用方式是多次请求使用相同的 HttpClient 所以这个 cookie 隔离性就很差,我们可以在创建 HttpClient 的时候进行配置禁用 cookie 自动处理,默认值为 true,建议设置为 false。
常用方法
Dispose ():释放产生的所有资源。
如果在实例化 HttpClient 时设置了 disposeHandler 属性为 true,就会在释放 HttpClient 时自动释放 SocketsHttpHandler 实例,就不需要调用该方法了
使用示例
var socketsHttpHandler = new SocketsHttpHandler()
{
UseCookies = false,
AutomaticDecompression = DecompressionMethods.None,
ConnectTimeout = Timeout.InfiniteTimeSpan,
MaxConnectionsPerServer = 10,
PooledConnectionIdleTimeout = TimeSpan.FromMinutes(1),
PooledConnectionLifetime = Timeout.InfiniteTimeSpan
};
var client = new HttpClient(socketsHttpHandler,true)
{
BaseAddress = new Uri("http://localhost:5500/"),
};
指示 HttpClient 操作是在响应可利用时立即视为已完成,还是在读取包含上下文的整个答案信息之后才视为已完成。
枚举值
ResponseContentRead:返回整个响应内容之后完成。默认值,一般不设置ResponseHeadersRead:返回响应头之后完成。
使用示例
var client = new HttpClient(socketsHttpHandler, true)
{
BaseAddress = new Uri("http://localhost:5500/"),
};
var res = await client.GetAsync("", HttpCompletionOption.ResponseContentRead).ConfigureAwait(false);
表示 HTTP 实体正文和内容标头的基类。该类型是抽象类型,可以使用派生类有:
ByteArrayContent:提供基于字节数组的 HTTP 内容。FormUrlEncodedContent:使用应用程序/x-www-form-urlencoded MIME 类型编码的名称/值元组的容器。
StringContent:基于字符串提供 HTTP 内容。
JsonContent:提供基于 JSON 的 HTTP 内容。
MultipartContent:提供 HttpContent 对象的集合,其可通过使用多部分/* 内容类型规范序列化。
MultipartFormDataContent:为使用 multipart/form-data MIME 类型进行编码的内容提供容器。
ReadOnlyMemoryContent:提供基于 ReadOnlyMemory
StreamContent:基于流提供 HTTP 内容。
常用的方法
ReadAsStringAsync ():将 HTTP 内容序列化到字符串,此为异步操作。ReadAsStreamAsync ():将 HTTP 内容序列化并返回将内容表示为异步操作的流。
ReadAsByteArrayAsync ():将 HTTP 内容序列化到字节数组,此为异步操作。
CopyToAsync (Stream):将 HTTP 内容序列化为字节流,并将其复制到作为 stream 参数提供的流对象。
CreateContentReadStreamAsync ():采用异步操作将 HTTP 内容序列化到内存流。
ByteArrayContent 使用示例(发送给服务端一张图片)
var client = new HttpClient()
{
BaseAddress = new Uri("http://127.0.0.1:5500/"),
};
var url = "UserManage/User/Test";
var bytes = await File.ReadAllBytesAsync(@"C:\Users\15423\Pictures\Screenshots\1.png").ConfigureAwait(false);
var content = new ByteArrayContent(bytes);
content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
using HttpResponseMessage response = await client.PostAsync(url, content).ConfigureAwait(false);
Console.ReadKey();
服务端保存到桌面
[HttpPost]
public async void Test()
{
var file = new FileStream(@"C:\Users\15423\Desktop\1.png", FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write);
await Request.Body.CopyToAsync(file);
file.Dispose();
}
StringContent 使用示例
var json = JsonConvert.SerializeObject(new { Name = "hello" });
StringContent content = new StringContent(json, Encoding.UTF8, "application/json");
using HttpResponseMessage response = await client.PostAsync("", content).ConfigureAwait(false);
表示请求和响应中的媒体类型信息。它用来告诉服务端如何处理请求的数据,以及告诉客户端(一般是浏览器)如何解析响应的数据,比如显示图片,解析并展示 html 等等。
表示包括状态代码和数据的 HTTP 响应消息。
常用的 http 请求方法,一般返回类型都是 Task<HttpResponseMessage> 类型,例如:
GetAsyncDeleteAsyncPostAsyncPutAsyncSendAsync
常用的属性
Content:HttpContent 类型,获取或设置 HTTP 响应消息的内容。Headers:HttpResponseHeaders 类型,获取 HTTP 响应标头的集合。
IsSuccessStatusCode:bool 类型,获取一个值,该值指示 HTTP 响应是否成功。
StatusCode:HttpStatusCode 枚举类型,获取或设置 HTTP 响应的状态代码,一般判断该属性等于 HttpStatusCode.Ok 就表示请求成功了
常用方法
Dispose():释放与该实例有关的所有的资源EnsureSuccessStatusCode():如果 HTTP 响应的 IsSuccessStatusCode 属性是 false,则引发异常,如果调用成功,HTTP 则响应消息。
使用示例
var client = new HttpClient()
{
BaseAddress = new Uri("http://www.baidu.com/"),
};
using HttpResponseMessage response = await client.GetAsync("").ConfigureAwait(false);
if (response != null)
{
if (response.IsSuccessStatusCode && response.StatusCode == HttpStatusCode.OK)
{
var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
if (string.IsNullOrEmpty(data))
{
Console.WriteLine(data);
}
}
}
Console.ReadKey();
释放建议使用 using,也可以使用 Dispose()方法
表示一条 HTTP 请求消息。该类只用于使用 SendAsync() 方法异步发送的 http 请求
常用构造函数
HttpRequestMessage ()
HttpRequestMessage (HttpMethod method, String requestUri)
参数介绍:
method:enum 类型,设置 HTTP 请求的方法,例如 HttpMethod.Get,HttpMethod.Post,因此使用该类可以发送任何请求方法requestUri:一个表示请求 Uri 的字符串。
常用的属性
Content:HttpContent 类型,获取或设置 HTTP 消息的内容。Headers:HttpRequestHeaders 类型,获取 HTTP 请求标头的集合。
Method:HttpMethod 类型,获取或设置 HTTP 请求消息使用的 HTTP 方法。
RequestUri:Uri 枚举类型,获取或设置用于 HTTP 请求的 Uri。
常用方法
Dispose():释放与该实例有关的所有的资源使用示例放到 SendAsync() 方法的使用方式中
在 HttpClient 中的 Get 请求方法有以下几种(常用方法就是 GetAsync)
GetAsync():返回 HttpResponseMessage 类型,表示异步操作的任务对象。GetByteArrayAsync():返回 byte[] 类型
GetStreamAsync():返回 Stream 类型
GetStringAsync():返回 string 类型
GetAsync 示例
var client = new HttpClient()
{
BaseAddress = new Uri("http://127.0.0.1:5500/"),
};
var url = "UserManage/User/TestGet";
using var response = await client.GetAsync(url).ConfigureAwait(false);
if (response != null && response.IsSuccessStatusCode && response.StatusCode == HttpStatusCode.OK)
{
var res = await response.Content.ReadAsStringAsync();
Console.WriteLine(res);
}
GetByteArrayAsync 示例
var response = await client.GetByteArrayAsync(url).ConfigureAwait(false);
foreach (var item in response)
{
Console.WriteLine(item);
}
Console.WriteLine(Encoding.UTF8.GetString(response));
GetStreamAsync 示例
var response = await client.GetStreamAsync(url).ConfigureAwait(false);
var memory = new MemoryStream();
await response.CopyToAsync(memory);
memory.Seek(0, SeekOrigin.Begin);
var bytes = new byte[memory.Length];
memory.Read(bytes, 0, bytes.Length);
response.Dispose();
memory.Dispose();
Console.WriteLine(Encoding.UTF8.GetString(bytes));
GetStringAsync 示例
var response = await client.GetStringAsync(url).ConfigureAwait(false);
Console.WriteLine(response);
Post 请求不会阻止。
PostAsync ():返回 HttpResponseMessage 类型,表示异步操作的任务对象。使用示例
var client = new HttpClient()
{
BaseAddress = new Uri("http://127.0.0.1:5500/"),
};
var url = "UserManage/User/TestPost";
var content = new StringContent("", Encoding.UTF8, "application/json");
var response = await client.PostAsync(url, content).ConfigureAwait(false);
if (response != null && response.IsSuccessStatusCode && response.StatusCode == HttpStatusCode.OK)
{
var res = await response.Content.ReadAsStringAsync();
Console.WriteLine(res);
}
Console.ReadKey();
使用 SendAsync ()方法发送 http 请求可以发送所有类型的 http 请求方法,比如 Get、Post 等,使用 SendAsync ()方法要搭配 HttpRequestMessage 使用
SendAsync (HttpRequestMessage request):返回 HttpResponseMessage 类型,表示异步操作的任务对象。
发送 Get 请求示例
var client = new HttpClient()
{
BaseAddress = new Uri("http://127.0.0.1:5500/"),
};
var url = "UserManage/User/TestGet";
var content = new StringContent("", Encoding.UTF8, "application/json");
var request = new HttpRequestMessage(HttpMethod.Get, url);
request.Content = content;
request.Headers.Add("Authorization", "Bearer xxxx");
var response = await client.SendAsync(request).ConfigureAwait(false);
if (response != null && response.IsSuccessStatusCode && response.StatusCode == HttpStatusCode.OK)
{
var res = await response.Content.ReadAsStringAsync();
Console.WriteLine(res);
}
Console.ReadKey();
发送 Post 请求示例
var client = new HttpClient()
{
BaseAddress = new Uri("http://127.0.0.1:5500/"),
};
var url = "UserManage/User/TestPost";
var content = new StringContent("", Encoding.UTF8, "application/json");
var request = new HttpRequestMessage(HttpMethod.Post, url);
request.Content = content;
request.Headers.Add("Authorization", "Bearer xxxx");
var response = await client.SendAsync(request).ConfigureAwait(false);
if (response != null && response.IsSuccessStatusCode && response.StatusCode == HttpStatusCode.OK)
{
var res = await response.Content.ReadAsStringAsync();
Console.WriteLine(res);
}
Console.ReadKey();
发送 http 请求时,推荐使用 SendAsync ()方法,当发送 get 请求需要使用请求头时,只能使用该方法了

浙公网安备 33010602011771号