Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting Accept Header without using MediaTypeWithQualityHeaderValue

In Asp.Net Web Api 2 what is the difference between setting an HttpClient Accept Header using the following traditional method :

        HttpClient client = HttpClientFactory.Create(handler);

        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

and the following method :

var headers = new Dictionary<string, string>
            {
                {"Accept", "application/json"}};

headers.ForEach(h => client.DefaultRequestHeaders.Add(h.Key, h.Value));

Update 1:

Based on the answer by @DarrenMiller in the following post What is the overhead of creating a new HttpClient per call in a WebAPI client? it appears that the preferred method is using DefaultRequestHeaders property because it contains properties which are intended for multiple calls. Does this mean if I set a default header using a simple dictionary my HttpClient client will not be as efficient as the one which uses DefaultRequestHeaders? In addition I really cant understand how the values inside DefaultRequestHeaders will be reused? Lets say I create 20 HttpClient client using HttpClientFactory.Create and inside every single one of them I set DefaultRequestHeaders property [Do I really need to do it because DefaultRequestHeaders was meant to be reused?!]. Where does this reuse kick-in and does setting the DefaultRequestHeaders every time I create a HttpClient client result in some kind of performance hit?

like image 429
MHOOS Avatar asked Jun 04 '15 16:06

MHOOS


1 Answers

Part one of your question: Is there any difference for adding headers?

HttpClient client = HttpClientFactory.Create(handler);

Method 1:

client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

Method 2:

var headers = new Dictionary<string, string>{{"Accept", "application/json"}};
headers.ForEach(h => client.DefaultRequestHeaders.Add(h.Key, h.Value));

Method 1 gives you nice strongly typed values with the ability to add multiple accept types. Method 2 has one more "magic string" that could be a place for typos and there is no way to add multiple accept types.

Part 2 of your question: Where is the performance and reuse value?

The performance hit of using a new HttpClient for every request depends on your use case. Get a bench mark and measure to see if it matters. The performance on the developer is most likely where the gains will be. Consider that every HttpClient you use you have to remember a bunch of headers to add. If you forget to add a proper header, errors happen. So, you can use DefaultRequestHeaders to set these up in a factory.

public class ApiService
{
    public static HttpClient GetClient()
    {
        var client = new HttpClient(new Uri("https://someservice/"));
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    
        //add any other setup items here.
        return client;
    }
}

Now use it:

public async Task DoStuff()
{
    using(var client = ApiService.GetClient())
    {
        //client will have the proper base uri and all the headers set.
        var data = await client.GetAsync<dynamic>("Sales");

        //client will still have the proper base uri and all the headers set.
        var data2 = await client.GetAsync<dynamic>("Products");
    }
}

HttpClients should be short lived and always wrapped in a using statement. The reuse occurs when multiple requests are made using the same client.

UPDATE:

As others have mentioned, Microsoft recommends keeping one HttpClient for the life of the application to avoid excess overhead. The preferred way to get an HttpClient would be having a static one declared and then reference that as needed. Be aware that anything set in the default headers will go out with every request so make sure you don't put things there such as Authorization unless you're sure of the final destination of the request.

like image 185
ManOVision Avatar answered Oct 21 '22 11:10

ManOVision