Injection of default headers to httpclient failing?

Viewed 214

My webapp relies on two strings for its api calls. I have tested that the api call works as expected when hard-coded. I have also verified that user-secrets holds the expected key-value pairs; my previous attempt using singleton ran into the issue of not being able to differentiate between the various strings coming from user-secrets.

My current attempt at implementation is to set the necessary headers in ConfigureServices:

services.AddHttpClient("OxfordDictionaryClient", _ =>
{
    _.DefaultRequestHeaders.Add("app_id", Configuration["app_id"]);
    _.DefaultRequestHeaders.Add("app_key", Configuration["app_key"]);
    _.DefaultRequestHeaders.Add("Accept", "application/json");
});

However, it seems none of this is being carried into the class where the method is called:

public class IndexModel : PageModel
{
    private readonly ILogger<IndexModel> _logger;
    private HttpClient _client;

    public IndexModel(ILogger<IndexModel> logger, HttpClient client)
    {
        _logger = logger;
        _client = client;
    }

    [BindProperty]
    public WordsInput Delivery { get; set; }

    public string synonyms { get; set; }

    public async Task<IActionResult> OnPostAsync()
    {
        string word = "anger";

        var URL = $"https://od-api.oxforddictionaries.com/api/v2/thesaurus/en/{word}?fields=synonyms&strictMatch=false";
        //_client.DefaultRequestHeaders.Add("app_id", ABC);
        //_client.DefaultRequestHeaders.Add("app_key", XYZ);
        //_client.DefaultRequestHeaders.Add("Accept", "application/json");

        var response = await _client.GetAsync(URL);
        var result = await response.Content.ReadAsStringAsync();
        JObject obj = JObject.Parse(result);
        synonyms = obj.ToString();

        return Page();
    }
}

I can see _client has none of my expected headers with a breakpoint on the line where the URL is set. Setting the headers directly in this class (the commented out code) works as expected, so the issue seems to be in the AddHttpClient not holding onto the headers added in ConfigureServices.

1 Answers

For the best practice of setting headers in ConfigureServices using httpclient, you can refer to the following code:

Startup.cs:

services.AddHttpClient("OxfordDictionaryClient", c =>
{
     c.DefaultRequestHeaders.Add("app_id", "testId");
     c.DefaultRequestHeaders.Add("app_key", "testKey");
     c.DefaultRequestHeaders.Add("Accept", "application/json");
});

PageModel:

public class PrivacyModel : PageModel
{
    private readonly ILogger<PrivacyModel> _logger;
    private readonly IHttpClientFactory _clientFactory;
    public PrivacyModel(ILogger<PrivacyModel> logger, IHttpClientFactory clientFactory)
    {
        _logger = logger;
        _clientFactory = clientFactory;
    }

    public async Task OnGet()
    {
        string word = "anger";
        var URL = $"https://od-api.oxforddictionaries.com/api/v2/thesaurus/en/{word}?fields=synonyms&strictMatch=false";
        var request = new HttpRequestMessage(HttpMethod.Get,
            URL);
        //Consistent with the name in ConfigureServices
        var client = _clientFactory.CreateClient("OxfordDictionaryClient");
        Console.WriteLine(client.DefaultRequestHeaders);
        var response = await client.SendAsync(request);
        var result = await response.Content.ReadAsStringAsync();
    }
}

Test Result: enter image description here

For more details, please refer to this link.

Related