在项目中需要访问Http请求的时候,通常都是使用WebRequest,主要是老项目(你懂得).如果不是老项目,应该使用HttpClient,但在.NET Core 2.1之后,官方可推荐使用使用HttpClientFactory.
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);
}
在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 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 HttpClient
services.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 HttpClient
services.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;
}
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
//在Asp.Net 6中,使用Minimal api
builder.Services.AddHttpClient("test", client =>
{
client.BaseAddress = new Uri("http://localhost:5000");
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
//在这里注入IHttpClientFactory
app.MapGet("/", async (IHttpClientFactory httpClientFactory) =>
{
var client = httpClientFactory.CreateClient("test");
return await client.GetStringAsync("/");
});
app.Run();
在Asp.Net Core 6中使用Minimal API简化项目