A .net library for configuring HttpClient instances from IConfiguration sources such as the appsettings.json file through dependency injection.
To start using the configuration for any HttpClient, simply invoke AddHttpClientConfiguration on your IServiceCollection instance. When invoked without arguments, the AddHttpClientConfiguration will use the section named Http from the global IConfiguration instance resolved from the container. You can configure this behavior by providing configureAction delegate.
Basic usage:
var builder = Host.CreateApplicationBuilder();
// Add default IHttpClientFactory implementation.
builder.Services.AddHttpClient();
// Allow HttpClient instances to be configured.
builder.Services.AddHttpClientConfiguration();We can specify the root configuration section name:
builder.Services.AddHttpClientConfiguration(options =>
{
// "Http" is the default value for the GlobalConfigurationSectionPath.
options.GlobalConfigurationSectionPath = "Http";
// We can use entire global IConfiguration instance by specifying
// null or empty string in the GlobalConfigurationSectionPath.
options.GlobalConfigurationSectionPath = null;
});We can also provide our own IConfiguration instance:
builder.Services.AddHttpClientConfiguration(options =>
{
// The GlobalConfigurationSectionPath will be ignored
// when we provide the explicit Configuration.
options.Configuration = new ConfigurationBuilder()
// ... add some providers here ...
.Build();
});We can configure our clients manually. The configuration from IConfiguration instance will be provided on top of that (since it is applied with IPostConfigureOptions<HttpClientFactoryOptions>).
builder.Services.AddHttpClientConfiguration();
builder.Services.AddHttpClient<OurClientType>()
.ConfigureHttpClient(httpClient =>
{
// This address can be overridden with
// "Http:OurClientType:BaseAddress" configuration key.
// The "Http:BaseAddress" key will also be consulted when
// "Http:OurClientType:BaseAddress" is not specified.
httpClient.BaseAddress = new Uri(
"https://default.base.address/",
UriKind.Absolute);
});The following properties of the HttpClient can be configured:
- BaseAddress.
- Timeout.
- DefaultRequestHeaders. Will be read from
Headerssection.
The following properties of the underlying HttpClientHandler can be configured:
- AllowAutoRedirect.
- Proxy. This is configured using
ProxyUrlconfiguration option. IfProxyUrlis not empty, aWebProxyinstance will be created with this url. TheWebProxy.Credentialsproperty is initialized toNetworkCredentialinstance with the following properties read from options:- UserName. Will be read from
ProxyUserName. - Password. Will be read from
ProxyPassword. - Domain. Will be read from
ProxyDomain.
- UserName. Will be read from
HttpClient configuration is organized hierarchically. Consider the following example from appsettings.json:
{
"Http": {
"BaseAddress": "https://www.mydomain.com/mypath/",
"Timeout": "0:00:20",
"Parent": {
"Timeout": "0:01:00",
"Child": {
"BaseAddress": "http://www.childaddress.com/"
}
}
}
}With this configuration, the unnamed HttpClient will have the BaseAddress equal to "https://www.mydomain.com/mypath/" and its Timeout will be 20 seconds. The HttpClient named "Parent" will have the same base address but its timeout will be one minute. The HttpClient with name "Parent:Child" will have the BaseAddress of "http://www.childaddress.com/", ant its timeout will be one minute.
The proxy for an HttpClientHandler will be inherited as long as BaseAddress is not overridden. When BaseAddress is overridden (even if the same as its parent), the proxy is no longer inherited and should be specified explicitly.
Consider the following configuration:
{
"Http": {
"A": {
"BaseAddress": "https://www.one.org/",
"B": {
"ProxyUrl": "http://myproxy/",
"C": {
"BaseAddress": "https://www.two.org/",
"D": {
"ProxyUrl": "http://myproxy/"
}
}
}
}
}
}Http clients named "A" and "A:B:C" will not have a proxy, but clients named "A:B", "A:B:C:D" and "A:B:C:D:anything" will.
When BaseAddress is applied from IConfiguration instance, the following rules are checked:
- The address should be absolute. Relative
Uricannot be assigned toHttpClient.BaseAddressanyway. AbsolutePathof the address should end with'/'. This ensures that configured address will be used exactly as specified when making requests. For example, if the base address would be specified as"https://domain/root/path"(not ending with'/') then when performinghttpClient.GetAsync("address")the request will be made to"https://domain/root/address"and not to"https://domain/root/path/address"as one might expect. We therefore prohibit paths not ending with'/'. This rule is not enforced whenHttpClientis configured in code.
You can configure headers as plain values as well as arrays.
{ "Http": { "Client": { "Headers": { "Header1": "value1", "Header2": ["a", "b", "c"] }, "Inherited": { "Headers": { // inherit Header1 but not Header2 "Header2": null } } } } }