NetCoreWeb中HttpClient使用全过程解析

本文最后更新于:2021年9月29日 下午

关于我

我的博客 | 欢迎关注

引言

在后端开发中,我们经常会调用到第三方的APi,微软考虑到了这种需求,所以在 .NET Framework 4.x 的时候引入了 HttpClient。但 HttpClient 有很多严重问题,一直饱受诟病,例如 HttpClient 不能立即关闭连接、性能消耗严重等的问题。

为了解决这些问题,从.NET Core 2.1 开始引入了 HttpClientFactory 解决了 HttpClient 的所有痛点。有了 HttpClientFactory,我们不需要关心如何创建 HttpClient,又如何释放它。通过它可以创建具有特定业务的 HttpClient,而且可以很友好的和 DI 容器结合使用,更为灵活。

本文主要是针对如何创建和使用HttpClient做一个说明。

应用说明

首先

首先,无论何用何种方式 。我们要做的第一件事情一定是服务的注册。在 Startup.cs 文件的 ConfigureServices 添加如果代码

1
services.AddHttpClient();

下方通过三种不同的方式,访问www.baidu.com并返回对应的html结果。

首先注入IHttpClientFactory

1
2
3
4
5
private readonly IHttpClientFactory _httpClientFactory;
public HttpClientController(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}

第一种方式 | 直接使用

这种方式最直接,也最容易理解。就是通过工厂创建一个httpclient,然后定义内容发起请求,获得结果。

1
2
3
4
5
6
7
8
[HttpGet("getbaidu")]
public async Task<ActionResult> GetBaidu()
{
var client = _httpClientFactory.CreateClient();
client.BaseAddress = new Uri("http://www.baidu.com");
string result = await client.GetStringAsync("/");
return Ok(result);
}

第二种方式 | 命名式方式

命名式方式是基于第一种方式的封装,相当于定义一次全局使用。但是因为所有配置信息都要在服务中进行注册,当如果有N个命名时,所有的信息如果都在serivces中注册一遍就总有一种怪怪的感觉,感觉封装的不人性化。

第一步在ConfigureServices中配置带有特定名称的 HttpClient 服务。将把案例一中的服务进行配置,内容如下

1
2
3
4
services.AddHttpClient("baidu", c =>
{
c.BaseAddress = new Uri("http://www.baidu.com");
});

第二步 api中使用些命名的httpClient服务

可以看到区别其实就是在于CreateClient中的参数传递了“baidu”,就会调用注入的内容初始化配置。

1
2
3
4
5
6
7
[HttpGet("GetBaiduClient")]
public async Task<ActionResult> GetBaiduClient()
{
var client = _httpClientFactory.CreateClient("baidu");
string result = await client.GetStringAsync("/");
return Ok(result);
}

第三种方式 | 类型化使用方式

这种方式是最推荐的。最个人为谁符合编码理解和封装的一种方式。

用程序员理解的方式就是,定义一个访问第三方的HttpClient类。里面包含了涉及此第三方访问的所有配置信息,请求方法。什么地方要使用,就通过构造函数将这个HttpClient构造出来,然后定义好的方法使用。

1、将案例一中的逻辑转换为一个通用的类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class BaiduHttpClient
{
public HttpClient _client { get; private set; }

public BaiduHttpClient(HttpClient httpClient)
{
httpClient.BaseAddress = new Uri("http://www.baidu.com");
_client = httpClient;
}


public async Task<string> GetBaidu()
{
return await _client.GetStringAsync("/");
}
}

2、如何要正常使用,需要为这个类注册服务

1
services.AddHttpClient<BaiduHttpClient>();

3、api中构造函数实例化,调用请求方法

1
2
3
4
5
6
7
8
9
10
11
12
13
private readonly BaiduHttpClient _baiduHttpClient;

public HttpClientController(BaiduHttpClient baiduHttpClient)
{
_baiduHttpClient = baiduHttpClient;
}

[HttpGet("GetBaiduClient2")]
public async Task<ActionResult> GetBaiduClient2()
{
string result = await _baiduHttpClient.GetBaidu();
return Ok(result);
}

总结

其实总体来说这三种方法没有高低之分,只是使用场景不同选择不同的方式。当然如果我们是一个追求代码规范性的程序员,我们其实更多地应该使用第三种方式,当然使用还不够,还要理解为什么第三种方式最好,优势在哪里,这才是最重要的。

参考资料

官方文档|在 ASP.NET Core 中使用 IHttpClientFactory 发出 HTTP 请求

.NET Core中使用HttpClient的正确姿势

The END

本文到此结束,希望对你有帮助 😃

更多精彩 技术文章汇总在我的 公众号程序员工具集 ,持续更新,欢迎关注订阅收藏。

如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

福利姬

公众号后台回复:“关注礼包”,获取价值5K的视频学习资源

公众号后台回复:“技能图谱”,送你一份最全的开发者技能图谱


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!