28

What is the difference between these two calls? My end goal is to have Accept: application/json sent over the wire, not to append to some default set of other MIME types.

HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Accept", "application/json");

vs.

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

My CLR is .NET Core 2.0.

Sniffing the wire reveals no difference:

# just .Add("Accept"...
~ % nc -l 8000
GET / HTTP/1.1
Connection: Keep-Alive
Accept: application/json
[...]

# with MediaTypeWithQualityHeaderValue
~ % nc -l 8000
GET / HTTP/1.1
Connection: Keep-Alive
Accept: application/json
[...]

So, outside the bizarre naming of that type, nothing else to gain here right?

evilSnobu
  • 19,691
  • 5
  • 31
  • 62
  • Have you used something like [fiddler](https://stackoverflow.com/questions/22500299/how-can-i-trace-the-httpclient-request-using-fiddler-or-any-other-tool#31136258) to see the difference? I'm not sure there is one but I haven't tried it. – Cake or Death Nov 08 '17 at 09:38
  • I just did the same test and observed no differences in the requests produced. Only difference would appear to be the syntax. As the previous commenter noted, with the second approach you could presumably chain media types. – Cake or Death Nov 08 '17 at 09:53
  • There is no difference. `DefaultRequestHeaders` provides shortcuts to some of the most used headers like `Accept`. – Panagiotis Kanavos Nov 08 '17 at 10:02
  • 2
    As for the name, it's not bizarre, that's how [those HTTP headers are called in the standard](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html). Those headers can have an additional quality factor, eg `Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5` – Panagiotis Kanavos Nov 08 '17 at 10:06
  • Very near previous question [here](https://stackoverflow.com/q/42007325/1178314) with explanations about this class. – Frédéric Nov 08 '17 at 10:10

3 Answers3

19

There is no difference.

DefaultRequestHeaders.Accept is a collection of string type, where you can add your header to accept using the new instance of MediaTypeWithQualityHeaderValue.

client.DefaultRequestHeaders is a dictionary that accepts key for and value for the request header and matches the results according to them.

DefaultRequestHeaders

has overloads.

The only thing that differs between them, is the fact that DefaultRequestHeaders.Accept will require you to initialize a new instance of MediaTypeWithQualityHeaderValue class, resulting in another reference type in the heap, while client.DefaultRequestHeaders will add the data to the dictionary, removing the cost of resources and the need to initialize a new instance.

It is really up to the user as to how and what to use.

Barr J
  • 9,047
  • 1
  • 22
  • 41
  • 7
    There *is* a difference. One method accepts everything, even if it's malformed. The other specifically accepts media types with a quality factor – Panagiotis Kanavos Nov 08 '17 at 10:18
9

There's no difference in the end result, as long as the names and values are correct.

The HTTP standard specifies that certain headers have a quality factor, hence the name MediaTypeWithQualityHeaderValue. It's a MediaType header value that can have a Quality factor. You can pass the quality factor if you use the MediaTypeWithQualityHeaderValue Constructor (String, Double) constructor

The Accept header section in the standard shows several examples that use the quality factor. For example,

The example

   Accept: audio/*; q=0.2, audio/basic

SHOULD be interpreted as "I prefer audio/basic, but send me any audio type if it is the best available after an 80% mark-down in quality."

You could write that with

var requestAccepts=client.DefaultRequestHeaders.Accept;
requestAccepts.Add(new MediaTypeWithQualityHeaderValue("audio/*",0.2));
requestAccepts.Add(new MediaTypeWithQualityHeaderValue("audio/basic"));

Or you can enter the raw header value with :

client.DefaultRequestHeaders.Add("Accept", "audio/*; q=0.2, audio/basic");
Panagiotis Kanavos
  • 90,087
  • 9
  • 138
  • 171
0

I don't think there is a difference it's just an easier way to add standard headers through properties like Accept, also convenient to add custom headers through the Add method.

AJ -
  • 595
  • 3
  • 9
  • 1
    The thing is, that DefaultRequestHeaders.Accept will also limit you only to Accept while DefaultRequestHeaders.Add will give you flexibility and freedom of choice when the question of "what to use" comes. You just change the value in the dictionary and not the entire type. – Barr J Nov 08 '17 at 10:12