HttpClient使用

起因在项目中需要访问Http请求的时候,通常都是使用WebRequest,主要是老项目(你懂得).如果不是老项目,应该使用HttpClient,但在.Net Core 2.1之后,官方可推荐使用使用HttpClientFactory.
1. HttpClient的使用public static async void UseHttp(){//在项目中HttpClient要静态单实例//这里只是为了方便HttpClient httpClient = new HttpClient();httpClient.BaseAddress = new Uri("http://localhost:5000"); //要访问的基地址,ip加端口string result = await httpClient.GetStringAsync("/Home/GethtmlData");Console.WriteLine(result);}2.在Asp.Net Core使用HttpClientFactory在Startup文件的ConfigureServices函数,注册HttpClient中间件
//1.在容器中注册HttpClient中间件services.AddHttpClient("baidu", client =>{client.BaseAddress = new Uri("http://localhost:5000");//还可以请求定制化});/// <summary>/// 在控制器中的构造函数注入IHttpClientFactory/// </summary>/// <param name="logger">日志</param>/// <param name="cache">缓存</param>/// <param name="httpClientFactory">容器在实例化HomeController的时候,会先实现IHttpClientFactory的实现DefaultHttpClientFactory(AddHttpClient在容器中注册)</param>public HomeController(ILogger<HomeController> logger,IMemoryCache cache,IHttpClientFactory httpClientFactory){Console.WriteLine("有参数构造 HomeController");this._logger = logger;this._httpClientFactory = httpClientFactory;}/// <summary>/// 在Action中使用HttpClient请求/// </summary>/// <returns></returns>public async Task<string> GetHtmlData(){//通过DefaultHttpClientFactory的CreateClient获取HttpClient实例var client = _httpClientFactory.CreateClient("baidu");return await client.GetStringAsync("/");}在Asp.Net Core的HttpClient中间件源码Asp.Net Core 5源码(2022.03.15,刚刚对比最新的代码,好像变化不大):
public static IServiceCollection AddHttpClient(this IServiceCollection services){if (services == null){throw new ArgumentNullException(nameof(services));}services.AddLogging();services.AddOptions();//// 向容器添加DefaultHttpClientFactory实例//services.TryAddTransient<HttpMessageHandlerBuilder, DefaultHttpMessageHandlerBuilder>();services.TryAddSingleton<DefaultHttpClientFactory>();services.TryAddSingleton<IHttpClientFactory>(serviceProvider => serviceProvider.GetRequiredService<DefaultHttpClientFactory>());services.TryAddSingleton<IHttpMessageHandlerFactory>(serviceProvider => serviceProvider.GetRequiredService<DefaultHttpClientFactory>());//// Typed Clients//services.TryAdd(ServiceDescriptor.Transient(typeof(ITypedHttpClientFactory<>), typeof(DefaultTypedHttpClientFactory<>)));services.TryAdd(ServiceDescriptor.Singleton(typeof(DefaultTypedHttpClientFactory<>.Cache), typeof(DefaultTypedHttpClientFactory<>.Cache)));//// Misc infrastructure//services.TryAddEnumerable(ServiceDescriptor.Singleton<IHttpMessageHandlerBuilderFilter, LoggingHttpMessageHandlerBuilderFilter>());// This is used to track state and report errors **DURING** service registration. This has to be an instance// because we access it by reaching into the service collection.services.TryAddSingleton(new HttpClientMAppingRegistry());// Register default client as HttpClientservices.TryAddTransient(s =>{return s.GetRequiredService<IHttpClientFactory>().CreateClient(string.Empty);});return services;}public static IHttpClientBuilder AddHttpClient(this IServiceCollection services, string name){if (services == null){throw new ArgumentNullException(nameof(services));}if (name == null){throw new ArgumentNullException(nameof(name));}AddHttpClient(services);return new DefaultHttpClientBuilder(services, name);}public static IHttpClientBuilder AddHttpClient(this IServiceCollection services, string name, Action<HttpClient> configureClient){if (services == null){throw new ArgumentNullException(nameof(services));}if (name == null){throw new ArgumentNullException(nameof(name));}if (configureClient == null){throw new ArgumentNullException(nameof(configureClient));}AddHttpClient(services);var builder = new DefaultHttpClientBuilder(services, name);builder.ConfigureHttpClient(configureClient);return builder;}public static IServiceCollection AddHttpClient(this IServiceCollection services){if (services == null){throw new ArgumentNullException(nameof(services));}services.AddLogging();services.AddOptions();//// Core abstractions//services.TryAddTransient<HttpMessageHandlerBuilder, DefaultHttpMessageHandlerBuilder>();services.TryAddSingleton<DefaultHttpClientFactory>();services.TryAddSingleton<IHttpClientFactory>(serviceProvider => serviceProvider.GetRequiredService<DefaultHttpClientFactory>());services.TryAddSingleton<IHttpMessageHandlerFactory>(serviceProvider => serviceProvider.GetRequiredService<DefaultHttpClientFactory>());//// Typed Clients//services.TryAdd(ServiceDescriptor.Transient(typeof(ITypedHttpClientFactory<>), typeof(DefaultTypedHttpClientFactory<>)));services.TryAdd(ServiceDescriptor.Singleton(typeof(DefaultTypedHttpClientFactory<>.Cache), typeof(DefaultTypedHttpClientFactory<>.Cache)));//// Misc infrastructure//services.TryAddEnumerable(ServiceDescriptor.Singleton<IHttpMessageHandlerBuilderFilter, LoggingHttpMessageHandlerBuilderFilter>());// This is used to track state and report errors **DURING** service registration. This has to be an instance// because we access it by reaching into the service collection.services.TryAddSingleton(new HttpClientMappingRegistry());// Register default client as HttpClientservices.TryAddTransient(s =>{return s.GetRequiredService<IHttpClientFactory>().CreateClient(string.Empty);});return services;}public static IHttpClientBuilder AddHttpClient(this IServiceCollection services, string name){if (services == null){throw new ArgumentNullException(nameof(services));}if (name == null){throw new ArgumentNullException(nameof(name));}AddHttpClient(services);return new DefaultHttpClientBuilder(services, name);}public static IHttpClientBuilder AddHttpClient(this IServiceCollection services, string name, Action<HttpClient> configureClient){if (services == null){throw new ArgumentNullException(nameof(services));}if (name == null){throw new ArgumentNullException(nameof(name));}if (configureClient == null){throw new ArgumentNullException(nameof(configureClient));}AddHttpClient(services);var builder = new DefaultHttpClientBuilder(services, name);builder.ConfigureHttpClient(configureClient);return builder;}


推荐阅读