I register a typed HttpClient with Startup and give it settings (BaseAddress and DefaultRequestHeaders). But these settings don't go to the HttpClient instance in the service. Instead, an HttpClient instance is instantiated with default settings.
To Reproduce
In Startup.cs
` public void ConfigureServices(IServiceCollection services)
{
var avazaBaseUrl = Configuration["Avaza:BaseUrl"];
var avazaAccessToken = Configuration["Avaza:PersonalAccessToken"];
services.AddHttpClient<IAvazaService, AvazaService>(client =>
{
client.BaseAddress = new Uri(avazaBaseUrl);
client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", avazaAccessToken);
});
services.AddServices();
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebApi", Version = "v1" });
});
}`
AvazaService.cs
` public class AvazaService : IAvazaService
{
private readonly HttpClient _httpClient;
public AvazaService(HttpClient httpClient)
{
_httpClient = httpClient; // BaseAddress is null, DefaultRequestHeaders is empty
}
public async Task<Result<List<Timesheet>>> GetTimesheets()
{
var response = await _httpClient.GetAsync("api/Timesheet");
if (!response.IsSuccessStatusCode)
return Result.Failure<List<Timesheet>>($"Avaza returns: '{(int)response.StatusCode} {response.ReasonPhrase}' on request in GetTimesheets method");
using var responseStream = await response.Content.ReadAsStreamAsync();
var timesheetList = await JsonSerializer.DeserializeAsync<TimesheetList>(responseStream);
return timesheetList.Timesheets;
}
}`
Exceptions (if any)
System.InvalidOperationException: An invalid request URI was provided. The request URI must either be an absolute URI or BaseAddress must be set.
at System.Net.Http.HttpClient.PrepareRequestMessage(HttpRequestMessage request)
at System.Net.Http.HttpClient.CheckRequestBeforeSend(HttpRequestMessage request)
at System.Net.Http.HttpClient.SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.GetAsync(String requestUri)
at WebApi.Services.AvazaService.GetTimesheets(Timesheet timesheetRequest) in C:\Users\Alexe\source\repos\HorizonOne\AvazaConnector\WebApi\Services\AvazaService.cs:line 26
at WebApi.Services.MainService.LoadTimesheets() in C:\Users\Alexe\source\repos\HorizonOne\AvazaConnector\WebApi\Services\MainService.cs:line 26
at WebApi.Controllers.MainController.LoadTimesheets() in C:\Users\Alexe\source\repos\HorizonOne\AvazaConnector\WebApi\Controllers\MainController.cs:line 34
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.gAwaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.gAwaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Further technical details
.NET 5.0.1
Пакет SDK для .NET (отражающий любой global.json):
Version: 5.0.101
Commit: d05174dc5a
Среда выполнения:
OS Name: Windows
OS Version: 10.0.19042
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\5.0.101\
Host (useful for support):
Version: 5.0.1
Commit: b02e13abab
Describe the bug
I register a typed HttpClient with Startup and give it settings (BaseAddress and DefaultRequestHeaders). But these settings don't go to the HttpClient instance in the service. Instead, an HttpClient instance is instantiated with default settings.
To Reproduce
In Startup.cs ` public void ConfigureServices(IServiceCollection services) { var avazaBaseUrl = Configuration["Avaza:BaseUrl"]; var avazaAccessToken = Configuration["Avaza:PersonalAccessToken"]; services.AddHttpClient<IAvazaService, AvazaService>(client => { client.BaseAddress = new Uri(avazaBaseUrl); client.DefaultRequestHeaders.Add("Accept", "application/json"); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", avazaAccessToken); });
AvazaService.cs ` public class AvazaService : IAvazaService { private readonly HttpClient _httpClient;
Exceptions (if any)
System.InvalidOperationException: An invalid request URI was provided. The request URI must either be an absolute URI or BaseAddress must be set. at System.Net.Http.HttpClient.PrepareRequestMessage(HttpRequestMessage request) at System.Net.Http.HttpClient.CheckRequestBeforeSend(HttpRequestMessage request) at System.Net.Http.HttpClient.SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken) at System.Net.Http.HttpClient.GetAsync(String requestUri) at WebApi.Services.AvazaService.GetTimesheets(Timesheet timesheetRequest) in C:\Users\Alexe\source\repos\HorizonOne\AvazaConnector\WebApi\Services\AvazaService.cs:line 26 at WebApi.Services.MainService.LoadTimesheets() in C:\Users\Alexe\source\repos\HorizonOne\AvazaConnector\WebApi\Services\MainService.cs:line 26 at WebApi.Controllers.MainController.LoadTimesheets() in C:\Users\Alexe\source\repos\HorizonOne\AvazaConnector\WebApi\Controllers\MainController.cs:line 34 at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.gAwaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Further technical details
Среда выполнения: OS Name: Windows OS Version: 10.0.19042 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\5.0.101\
Host (useful for support): Version: 5.0.1 Commit: b02e13abab
.NET SDKs installed: 5.0.101 [C:\Program Files\dotnet\sdk]
.NET runtimes installed: Microsoft.AspNetCore.All 2.1.23 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.1.23 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.10 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 2.1.23 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.10 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.1.10 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
To install additional .NET runtimes or SDKs: https://aka.ms/dotnet-download