In my .net core web api project I would like to hit an external API so that I get my response as expected.
The way I`m registering and using the HttpClient is as follows. In the startup, I'm adding the following code which is called named typed httpclient way.
services.AddHttpClient<IRecipeService, RecipeService>(c => {
c.BaseAddress = new Uri("https://sooome-api-endpoint.com");
c.DefaultRequestHeaders.Add("x-raay-key", "123567890754545645gggg");
c.DefaultRequestHeaders.Add("x-raay-host", "sooome-api-endpoint.com");
});
In addition to this, I have 1 service in which I inject the HttpClient.
public class RecipeService : IRecipeService
{
private readonly HttpClient _httpClient;
public RecipeService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<List<Core.Dtos.Recipes>> GetReBasedOnIngAsync(string endpoint)
{
using (var response = await _httpClient.GetAsync(recipeEndpoint))
{
// ...
}
}
}
When the httpClient is created, if I hover over the object itself, the base URI/Headers are missing, and I don't understand why exactly this is happening. I would appreciate if someone could show some light :)
UPDATE 1ST
The service is being used in one of the Controllers shown below. The service is injected by the DI and then the relative path is parsed to the service ( I assumed I already have the base URL stored in the client ) Maybe I`m doing it wrong?
namespace ABC.Controllers
{
[ApiController]
[Route("[controller]")]
public class FridgeIngredientController : ControllerBase
{
private readonly IRecipeService _recipeService;
private readonly IMapper _mapper;
public FridgeIngredientController(IRecipeService recipeService, IMapper mapper)
{
_recipeService = recipeService;
_mapper = mapper;
}
[HttpPost("myingredients")]
public async Task<ActionResult> PostIngredients(IngredientsDto ingredientsDto)
{
var readyUrIngredientStr = string.Join("%2", ingredientsDto.ingredients);
var urlEndpoint = $"recipes/findByIngredients?ingredients={readyUrIngredientStr}";
var recipesResponse = await _recipeService.GetRecipeBasedOnIngredientsAsync(urlEndpoint);
InMyFridgeRecipesDto recipesFoundList = new InMyFridgeRecipesDto
{
FoundRecipes = recipesResponse
};
return Ok(recipesFoundList);
}
}
}
Any suggestions?
A simple, frustrating reason this may happen is due to the order of your service collection statements.
Assigning the dependant service after the HTTPClient will not work, it must come before:
// NOT WORKING - BaseAddress is null
services.AddTransient<Controller1>();
services.AddTransient<Controller2>();
services.AddHttpClient<HttpService>(client =>
{
client.BaseAddress = new Uri(baseAdress);
});
services.AddTransient<HttpService>();
// WORKING - BaseAddress is not null
services.AddTransient<Controller1>();
services.AddTransient<Controller2>();
services.AddTransient<HttpService>();
services.AddHttpClient<HttpService>(client =>
{
client.BaseAddress = new Uri(baseAdress);
});
EDIT
As LIFEfreedom rightfully pointed out in their answer: while the order of the statements has an effect here, it is not the reason for behaviour.
Both of the following statements create a transient service for the HttpService
class:
services.AddTransient<HttpService>();
services.AddHttpClient<HttpService>();
However, when adding both of these statements only the latest one will be used, overwriting any statements before it. In my example, I only got the expected result when the AddHttpClient
statement with the base address configuration came last.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With