4

Sorry to ask this question like this. I can give you the feeling I would like you to do the code for me. I already spent a day tying to write the code to send a http request that contains a header with versioning:

For versioning I use the versioning by Media Type from Microsoft/aspnet-api-versioning project.

My API part is working fine and I can request the correct version without problem with Postman:

enter image description here

You see this line "Content-Type = application/json;v=2.0"? On postman no problem. With HttpClient from C# impossible to do.

Let me copy pas here all solution I tried with they error. I will Edit this question each time I try a new solution. By facility, but also to be more clear I will copy paste images:

Solution 1: The extension method with new Content = ...

enter image description here

Solution 1B: From BeginnerTejas

enter image description here

Solution 1C: From BeginnerTejas but using MediaTypeWithQualityHeaderValue now

enter image description here

Solution 2: The extension method with request.Headers.Add(...)

enter image description here

Solution 3: BaseProxy with Client.DefaultRequestHeaders.TryAddWithoutValidation(...) It seems I cannot add any "Content-Type"

enter image description here

Solution 4: BaseProxy with Client.DefaultRequestHeaders.Accept.Add(...)

enter image description here

Solution 5: request.Headers.TryAddWithoutValidation("Content-Type", "application/json");

enter image description here

Bastien Vandamme
  • 17,659
  • 30
  • 118
  • 200

2 Answers2

1

Can you try this?

request.Content.Headers.ContentType = new MediaTypeWithQualityHeaderValue( "application/json" )
{
    Parameters = { new NameValueHeaderValue( "v", "2.0" ) }
};
TejasGondalia
  • 168
  • 3
  • 13
1

You can't (or at least shouldn't) use Content-Type when you don't send any content. Use the Accept header for GET and DELETE requests like this:

request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json; v=2.0"));

If both headers are specified Content-Type is considered before Accept. If Accept specifies multiple media types with a version, the one with the highest quality is matched. Mixing versions per request (e.g. send 2.0, but receive 1.0) is not supported. Negotiating multiple media types with a version is also not currently supported (aside from quality).


UPDATE: I wanted to expand the answer to include the fact that there are now API version-aware client extensions (in Asp.Versioning.Http.Client) that make this process significantly simpler. For example:

var services = new ServiceCollection();

// register the default api version writer for all requests
services.AddSingleton<IApiVersionWriter>( new MediaTypeApiVersionWriter() );

// you can also provide a client-specific writer here ↓
services.AddHttpClient( "Example" ).AddApiVersion( 1.0 );

// using dependency injection with the http client factory
var provider = services.BuildServiceProvider();
var factory = provider.GetRequiredService<IHttpClientFactory>();
var client = factory.CreateClient( "Example" );

// this will add 'v=1.0' to Accept
var response = await client.GetAsync( "http://tempuri.org" );

// this will add 'v=1.0' to Content-Type
response = await client.PostJsonAsync( "http://tempuri.org", new { test = true } );

If you're not using the DI extensions or IHttpClientFactory you can still add the ApiVersionHandler directly to the handler chain in your HttpClient.

Chris Martinez
  • 3,185
  • 12
  • 28