How to set the Content-Type header for an HttpClient request?
Asked Answered
R

24

1134

I'm trying to set the Content-Type header of an HttpClient object as required by an API I am calling.

I tried setting the Content-Type like below:

using (var httpClient = new HttpClient())
{
    httpClient.BaseAddress = new Uri("http://example.com/");
    httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
    httpClient.DefaultRequestHeaders.Add("Content-Type", "application/json");
    // ...
}

It allows me to add the Accept header but when I try to add Content-Type it throws the following exception:

Misused header name. Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects.

How can I set the Content-Type header in a HttpClient request?

Rodgerrodgers answered 21/5, 2012 at 3:29 Comment(1)
You could follow how HttpWebRequest in .NET Core does it (it uses HttpClient internally), see github.com/dotnet/corefx/blob/master/src/System.Net.Requests/… "SendRequest" methodTogetherness
W
1393

The content type is a header of the content, not of the request, which is why this is failing. AddWithoutValidation as suggested by Robert Levy may work, but you can also set the content type when creating the request content itself (note that the code snippet adds application/json in two places-for Accept and Content-Type headers):

HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://example.com/");
client.DefaultRequestHeaders
      .Accept
      .Add(new MediaTypeWithQualityHeaderValue("application/json"));//ACCEPT header

HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "relativeAddress");
request.Content = new StringContent("{\"name\":\"John Doe\",\"age\":33}",
                                    Encoding.UTF8, 
                                    "application/json");//CONTENT-TYPE header

client.SendAsync(request)
      .ContinueWith(responseTask =>
      {
          Console.WriteLine("Response: {0}", responseTask.Result);
      });
Wormwood answered 21/5, 2012 at 3:54 Comment(15)
Alternatively, Response.Content.Headers will work most of the time.Cafard
@AshishJain Most of the SO answers I've seen involving Response.Content.Headers for the ASP.Net Web API haven't worked either, but you can easily set it using HttpContext.Current.Response.ContentType if you need to.Teddy
@Teddy i used in following way which worked for me. var content = new StringContent(data, Encoding.UTF8, "application/json");Pattipattie
Content-Type is a property of an HTTP message with payload; it has nothing to do with request vs response.Julian
Interesting. I tried creating a new StringContent with the three parameters and it didn't work. I then manually: request.Content.Headers.Remove("Content-Type") and then: request.Content.Headers.Add("Content-Type", "application/query+json") and it worked. Odd.Indomitable
StringContent should be dispossedCamorra
What is the "relativeAddress" bit?Ory
HttpClient should be reused (static) and used as such (do not set base address, default request headers etc.)Chura
This is bad. You should re-use HttpClient. DefaultRequestHeaders are only supposed to be used if you're using the HttpClient for many different related issues. HttpClient's are supposed to be closely related to instantiated as singletons. Aka re-used.Agar
relativeAddress is the urlUnplumbed
To be clear, System.Net.Http has provided a poor implementation here. Content-Type is an HTTP request header and an implementation that suggests otherwise is misleading and confusing. However, as you are using dotnet, you have to live with it. (developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type).Vaporize
@Wormwood According to Microsoft Documentation regarding the DefaultRequestHeaders it says: "Headers set on this property don't need to be set on request messages again." So you should not add Content-Type again in the HttpRequestMessage, just StringContent(String, Encoding) should be enough.Hedonic
For JSON content, as of .NET 5 you can do: requestMessage.Content = JsonContent.Create(new {Name = "John Doe", Age = 33}); and the Content-Type is set automatically.Adamite
` Console.WriteLine("Response: {0}", responseTask.Result);` can't compiled?Readiness
It's been quite a while since I last visited this post. FYI, some systems expect the Content-Type header on requests, but that was intended to only be a response header. That's why .NET was implemented with such a strict implementation, and setting it on a response does not help when the API you call expects it on the request. Thanks to @CraigBrown for the updated .NET usage! It also looks like .NET 5 added ReadFromJsonAsyncNewt
B
231
req.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
Burnley answered 6/6, 2013 at 10:15 Comment(4)
I had to throw .ToString() on the end, but yes this worked for a WCF service implementation.Americana
I will eventually figure out what object type "req" is ... by trial and error........BUT it would be great to show that. Thank you for your consideration.Anthracene
System.Net.Http.HttpRequestMessage from "microsoft.netcore.app\2.1.0\ref\netcoreapp2.1\System.Net.Http.dll" is where I found it.Anthracene
Just so folks know, using MediaTypeHeaderValue will return an error if attempting to set the charset, like so; response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/xml; charset=utf-8");Player
Z
63

If you don't mind a small library dependency, Flurl.Http [disclosure: I'm the author] makes this uber-simple. Its PostJsonAsync method takes care of both serializing the content and setting the content-type header, and ReceiveJson deserializes the response. If the accept header is required you'll need to set that yourself, but Flurl provides a pretty clean way to do that too:

using Flurl.Http;

var result = await "http://example.com/"
    .WithHeader("Accept", "application/json")
    .PostJsonAsync(new { ... })
    .ReceiveJson<TResult>();

Flurl uses HttpClient and Json.NET under the hood, and it's a PCL so it'll work on a variety of platforms.

PM> Install-Package Flurl.Http
Zabaglione answered 22/6, 2014 at 15:19 Comment(1)
How to send if content is application/x-www-form-urlencoded?Evie
M
49

.Net tries to force you to obey certain standards, namely that the Content-Type header can only be specified on requests that have content (e.g. POST, PUT, etc.). Therefore, as others have indicated, the preferred way to set the Content-Type header is through the HttpContent.Headers.ContentType property.

With that said, certain APIs (such as the LiquidFiles Api, as of 2016-12-19) requires setting the Content-Type header for a GET request. .Net will not allow setting this header on the request itself -- even using TryAddWithoutValidation. Furthermore, you cannot specify a Content for the request -- even if it is of zero-length. The only way I could seem to get around this was to resort to reflection. The code (in case some else needs it) is

var field = typeof(System.Net.Http.Headers.HttpRequestHeaders)
    .GetField("invalidHeaders", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static) 
  ?? typeof(System.Net.Http.Headers.HttpRequestHeaders) 
    .GetField("s_invalidHeaders", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
if (field != null)
{
  var invalidFields = (HashSet<string>)field.GetValue(null);
  invalidFields.Remove("Content-Type");
}
_client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "text/xml");

Edit:

As noted in the comments, this field has different names in different versions of the dll. In the source code on GitHub, the field is currently named s_invalidHeaders. The example has been modified to account for this per the suggestion of @David Thompson.

Mazur answered 19/12, 2016 at 21:32 Comment(5)
Not working with .Net Framework version 4.0, System.Net.Http version 2.2.29.0 but working with 2.0.0.0Slouch
This field is now s_invalidHeaders so using the following ensures compatibility: var field = typeof(System.Net.Http.Headers.HttpRequestHeaders) .GetField("invalidHeaders", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static) ?? typeof(System.Net.Http.Headers.HttpRequestHeaders) .GetField("s_invalidHeaders", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);Cloudlet
Awesome hack. Works for me, however, first time it does't apply the JSON header, but all subsequent calls it does. Anyone had similar behavior? I did work around it but any good hack around it?Washstand
I've noticed that if I use this in my API which calls a 3rd-party API the first request is successful but subsequent ones fail and I can't get it working again unless I restart IIS.Dundee
The problem with using this is that it breaks all the other API calls that didn't have this problem. I think because of the BindingFlags.Static which is required to make this work.Dagenham
J
48

try to use TryAddWithoutValidation

  var client = new HttpClient();
  client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json; charset=utf-8");
Jodyjoe answered 19/11, 2015 at 22:48 Comment(3)
not working gives me a 'Misused header name. Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects.'Quintain
Those of you reporting "working" or "not working", HttpClient is a very ambiguous object these days. Please report the fullname(space) and .dll assembly it is coming from.Anthracene
the Misused header name error is confirmed with dotnet core 2.2. I had to use @carlosfigueira's answer https://mcmap.net/q/45620/-how-to-set-the-content-type-header-for-an-httpclient-request.Newt
I
34

For those who troubled with charset

I had very special case that the service provider didn't accept charset, and they refuse to change the substructure to allow it... Unfortunately HttpClient was setting the header automatically through StringContent, and no matter if you pass null or Encoding.UTF8, it will always set the charset...

Today i was on the edge to change the sub-system; moving from HttpClient to anything else, that something came to my mind..., why not use reflection to empty out the "charset"? ... And before i even try it, i thought of a way, "maybe I can change it after initialization", and that worked.

Here's how you can set the exact "application/json" header without "; charset=utf-8".

var jsonRequest = JsonSerializeObject(req, options); // Custom function that parse object to string
var stringContent = new StringContent(jsonRequest, Encoding.UTF8, "application/json");
stringContent.Headers.ContentType.CharSet = null;
return stringContent;

Note: The null value in following won't work, and append "; charset=utf-8"

return new StringContent(jsonRequest, null, "application/json");

EDIT

@DesertFoxAZ suggests that also the following code can be used and works fine. (didn't test it myself, if it work's rate and credit him in comments)

stringContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
Impressure answered 18/8, 2019 at 7:19 Comment(3)
stringContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); also worksDundee
Was getting 415 Errors with UPS new API, constantly saying "Content-Type should be application/json" even though everything was set to application/json. Turns out setting the ContentType.CharSet = null worked for their api.Poetize
@Poetize I'm sorry to hear that, and glad you could fix it on your own, in my country, we are forbidden to use most foreign services, so I was afraid that I couldn't help you. I'm not sure if I also got the same error or something else, however, some systems use the code as they want and as it's defined and means in their team, it doesn't have, and not everything is fully standardized outImpressure
A
26

Some extra information about .NET Core (after reading erdomke's post about setting a private field to supply the content-type on a request that doesn't have content):

After debugging my code, I can't see the private field to set via reflection - so I thought I'd try to recreate the problem.

I have tried the following code using .NET 4.6:

HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Get, @"myUrl");
httpRequest.Content = new StringContent(string.Empty, Encoding.UTF8, "application/json");

HttpClient client = new HttpClient();
Task<HttpResponseMessage> response =  client.SendAsync(httpRequest);  //I know I should have used async/await here!
var result = response.Result;

And, as expected, I get an aggregate exception with the content

Cannot send a content-body with this verb-type.

However, if I do the same thing with .NET Core (1.1), I don't get an exception. My request was quite happily answered by my server application, and the content-type was picked up.

Ahumada answered 12/6, 2017 at 8:48 Comment(0)
I
22

Call AddWithoutValidation instead of Add (see this MSDN link).

Alternatively, I'm guessing the API you are using really only requires this for POST or PUT requests (not ordinary GET requests). In that case, when you call HttpClient.PostAsync and pass in an HttpContent, set this on the Headers property of that HttpContent object.

Impressionism answered 21/5, 2012 at 3:32 Comment(2)
AddWithoutValidation does not existSoulless
I believe what was meant was TryAddWithoutValidation; full reference is System.Net.Http.Headers.HttpHeaders.TryAddWithoutValidation.Daumier
S
21

The trick is that you can just set all kinds of headers like:

HttpRequestMessage request = new HttpRequestMessage();
request.Headers.Add("Accept-Language", "en"); //works OK

but not any header. For example:

request.Headers.Add("Content-Type", "application/json");//wrong

will raise the run-time exception Misused header name. It may seem that this will work:

request.Headers.Add(
   HttpRequestHeader.ContentType.ToString(), //useless
   "application/json"
);

but this gives a useless header named ContentType, without the hyphen. Header names are not case-sensitive, but are very hyphen-sensitive.

The solution is to declare the encoding and type of the body when adding the body to the Content part of the http request:

string Body = "...";
request.Content = new StringContent(Body, Encoding.UTF8, "application/json");

Only then the applicable http header is automatically added to the request, like:

Content-Type: application/json; charset=utf-8

It was hard to find this out, with Fiddler, on a machine without a proxy server. Visual Studio used to have a Network Tool where you could inspect all headers, but only in version 2015, not in newer versions 2017 or 2022. If you use the debugger to inspect request.Headers, you will not find the header added automagically by StringContent().

Screamer answered 5/1, 2022 at 13:20 Comment(4)
For some headers removing the "-" works, e.g request.Headers.Add("ContentType", "application/json")Circular
@Circular What do you mean with "works"? Sure, this does not give a build error. But the server will not recognize your ContentType header to set a content type, as I explained in my answer.Screamer
Some servers do, especially the old CMS systems. In fact, HttpRequestHeader.ContentType.ToString() produces "ContentType".Circular
@Circular Sure, but the original question was not how to set the ContentType header, but how to set the Content-Type header. If some RFC requires you to set some header, the header name is not case-sensitive, but sure is hyphen-sensitive. As I explained in my answer. Happy Holidays to you!Screamer
D
7

You can use this it will be work!

HttpRequestMessage msg = new HttpRequestMessage(HttpMethod.Get,"URL");
msg.Content = new StringContent(string.Empty, Encoding.UTF8, "application/json");

HttpResponseMessage response = await _httpClient.SendAsync(msg);
response.EnsureSuccessStatusCode();

string json = await response.Content.ReadAsStringAsync();
Danialdaniala answered 10/7, 2019 at 4:1 Comment(1)
This only works with .NET Core, not .NET Framework.Durkin
I
5

For anyone that needs the content-type header for Get etc., while in an older .NET version it is possible to use the answer of @erdomke at https://stackoverflow.com/a/41231353, this unfortunately no longer works in the newer .NET Core versions.

The following code has been tested to work with .NET Core 3.1 and from the source code on GitHub it looks like it should work with newer .NET versions as well.

private void FixContentTypeHeaders()
{
    var assembly = typeof(System.Net.Http.Headers.HttpRequestHeaders).Assembly;
    var assemblyTypes = assembly.GetTypes();

    var knownHeaderType = assemblyTypes.FirstOrDefault(n => n.Name == "KnownHeader");
    var headerTypeField = knownHeaderType?
                .GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
                .FirstOrDefault(n => n.Name.Contains("HeaderType"));
    if (headerTypeField is null) return;

    var headerTypeFieldType = headerTypeField.FieldType;            
    var newValue = Enum.Parse(headerTypeFieldType, "All");

    var knownHeadersType = assemblyTypes.FirstOrDefault(n => n.Name == "KnownHeaders");
    var contentTypeObj = knownHeadersType.GetFields().FirstOrDefault(n => n.Name == "ContentType").GetValue(null);

    if (contentTypeObj is null) return;

    headerTypeField.SetValue(contentTypeObj, newValue);
}
Inebriety answered 3/3, 2021 at 2:12 Comment(3)
Why is all this reflection necessary? It's the content object that dictates Content-Type, and you can add a content object on GET requests as well as POST, PUT, etc. If you don't have a content object (body) then Content-Type is an irrelevant header.Plasmosome
@John There are frameworks including Microsoft own frameworks that require the header even for a Get and even when there is no Content, don't ask me why.. and why their client removes it when their server expects it...Inebriety
Unless the Content-Length header presents a problem, isn't it better just to create a derived HttpContent object that allows you to specify the header rather than doing all this reflection?Plasmosome
K
4
var content = new JsonContent();
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
content.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("charset", "utf-8"));
content.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("IEEE754Compatible", "true"));

It's all what you need.

With using Newtonsoft.Json, if you need a content as json string.

public class JsonContent : HttpContent
   {
    private readonly MemoryStream _stream = new MemoryStream();
    ~JsonContent()
    {
        _stream.Dispose();
    }

    public JsonContent(object value)
    {
        Headers.ContentType = new MediaTypeHeaderValue("application/json");
        using (var contexStream = new MemoryStream())
        using (var jw = new JsonTextWriter(new StreamWriter(contexStream)) { Formatting = Formatting.Indented })
        {
            var serializer = new JsonSerializer();
            serializer.Serialize(jw, value);
            jw.Flush();
            contexStream.Position = 0;
            contexStream.WriteTo(_stream);
        }
        _stream.Position = 0;

    }

    private JsonContent(string content)
    {
        Headers.ContentType = new MediaTypeHeaderValue("application/json");
        using (var contexStream = new MemoryStream())
        using (var sw = new StreamWriter(contexStream))
        {
            sw.Write(content);
            sw.Flush();
            contexStream.Position = 0;
            contexStream.WriteTo(_stream);
        }
        _stream.Position = 0;
    }

    protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
    {
        return _stream.CopyToAsync(stream);
    }

    protected override bool TryComputeLength(out long length)
    {
        length = _stream.Length;
        return true;
    }

    public static HttpContent FromFile(string filepath)
    {
        var content = File.ReadAllText(filepath);
        return new JsonContent(content);
    }
    public string ToJsonString()
    {
        return Encoding.ASCII.GetString(_stream.GetBuffer(), 0, _stream.GetBuffer().Length).Trim();
    }
}
Krystynakshatriya answered 28/5, 2018 at 13:56 Comment(3)
Can you give a small explanation of what it does?Treble
The first line fails with CS0144: "Cannot create an instance of the abstract class or interface 'HttpContent'"Dendritic
and then HttpMessageHandler handler = new WebRequestHandler(); HttpResponseMessage result; using (var client = (new HttpClient(handler, true))) { result = client.PostAsync(fullUri, content).Result; }Krystynakshatriya
F
3

Ok, it's not HTTPClient but if u can use it, WebClient is quite easy:

using (var client = new System.Net.WebClient())
 {
    client.Headers.Add("Accept", "application/json");
    client.Headers.Add("Content-Type", "application/json; charset=utf-8");
    client.DownloadString(...);
 }
Fungous answered 9/7, 2018 at 20:21 Comment(0)
S
3

try to use HttpClientFactory

services.AddSingleton<WebRequestXXX>()
        .AddHttpClient<WebRequestXXX>("ClientX", config =>
        {
           config.BaseAddress = new System.Uri("https://jsonplaceholder.typicode.com");
           config.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
           config.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json; charset=utf-8");
        });

======================

public class WebRequestXXXX
{
    private readonly IHttpClientFactory _httpClientFactory;

    public WebRequestXXXX(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }

    public List<Posts> GetAllPosts()
    {
        using (var _client = _httpClientFactory.CreateClient("ClientX"))
        {
            var response = _client.GetAsync("/posts").Result;

            if (response.IsSuccessStatusCode)
            {
                var itemString = response.Content.ReadAsStringAsync().Result;
                var itemJson = System.Text.Json.JsonSerializer.Deserialize<List<Posts>>(itemString, 
                    new System.Text.Json.JsonSerializerOptions 
                    {
                        PropertyNameCaseInsensitive = true
                    });

                return itemJson;
            }
            else
            {
                return new List<Posts>();
            }
        }
    }
}
Stack answered 28/2, 2021 at 22:17 Comment(1)
Yeah, but don't use ReadAsStringAsync, ever, when deserializing json. Use ReadAsStream, and deserialize the stream.Culliton
L
3

I got the answer with RestSharp:

private async Task<string> GetAccessTokenAsync()
{
    var client = new RestClient(_baseURL);

    var request = new RestRequest("auth/v1/login", Method.POST, DataFormat.Json);

    request.AddHeader("Content-Type", "application/json");
    request.AddHeader("x-api-key", _apiKey);
    request.AddHeader("Accept-Language", "br");
    request.AddHeader("x-client-tenant", "1");

    ...
}

It worked for me.

Legitimatize answered 20/4, 2021 at 19:45 Comment(1)
But you are adding header to request, not to clientKopple
I
2

For those wanting to set the Content-Type to Json specifically, you can use the extension method PostAsJsonAsync.

using System.Net.Http.Json; //this is needed for PostAsJsonAsync to work
//....
HttpClient client = new HttpClient();
HttpResponseMessage response = await
    client.PostAsJsonAsync("http://example.com/" + "relativeAddress",
                new
                {
                    name = "John Doe",
                    age = 33
                });
//Do what you need to do with your response

The advantage here is cleaner code and you get to avoid stringified json. More details can be found at: https://learn.microsoft.com/en-us/previous-versions/aspnet/hh944339(v=vs.118)

Indiscrete answered 18/7, 2021 at 14:1 Comment(1)
problem I'm running into is that PostAsJsonAsync doesn't set the Content-type header!!Donne
C
1

You need to do it like this:

    HttpContent httpContent = new StringContent(@"{ the json string }");
    httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));                
    HttpResponseMessage message = client.PostAsync(@"{url}", httpContent).Result;
Charmine answered 9/8, 2019 at 18:55 Comment(0)
H
1

For my scenario, a third-party API was creating the HttpRequestMessage, so I was not able to use the top-voted answers to resolve the issue. And I didn't like the idea of messing with reflection so the other answers didn't work either.

Instead, I extended from AndroidMessageHandler and used this new class as a parameter to HttpClient. AndroidMessageHandler contains the method SendAsync which can be overridden in order to make changes to the HttpRequestMessage object before it is sent. If you don't have access to the Android Xamarin libaries, you may be able to figure something out with HttpMessageHandler.

public class XamarinHttpMessageHandler : global::Xamarin.Android.Net.AndroidMessageHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        // Here I make check that I'm only modifying a specific request
        // and not all of them.
        if (request.RequestUri != null && request.RequestUri.AbsolutePath.EndsWith("download") && request.Content != null)
        {
            request.Content.Headers.Add("Content-Type", "text/plain");
        }
        return base.SendAsync(request, cancellationToken);
    }
}

Then to use:

var client = new HttpClient(new XamarinHttpMessageHandler());
Heliopolis answered 3/1, 2023 at 19:48 Comment(0)
S
0

I find it most simple and easy to understand in the following way:

async Task SendPostRequest()
{
    HttpClient client = new HttpClient();
    var requestContent = new StringContent(<content>);
    requestContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    var response = await client.PostAsync(<url>, requestContent);
    var responseString = await response.Content.ReadAsStringAsync();
}
...

SendPostRequest().Wait();
Skirl answered 11/6, 2019 at 22:10 Comment(0)
O
0

Api returned

"Unsupported Media Type","status":415

Adding ContentType to the jsonstring did the magic and this is my script working 100% as of today

    using (var client = new HttpClient())
            {
                   var endpoint = "api/endpoint;
                    var userName = "xxxxxxxxxx";
                    var passwd = "xxxxxxxxxx";
                    var content = new StringContent(jsonString, Encoding.UTF8, "application/json");

                    var authToken = Encoding.ASCII.GetBytes($"{userName}:{passwd}");

                client.BaseAddress = new Uri("https://example.com/");

                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(authToken));
            
                HttpResponseMessage response = await client.PostAsync(endpoint, content);

                if (response.IsSuccessStatusCode)
                {
                    // Get the URI of the created resource.
                    Uri returnUrl = response.Headers.Location;
                    Console.WriteLine(returnUrl);
                }
                string responseBody = await response.Content.ReadAsStringAsync();
                return responseBody;
        }
Oriane answered 31/3, 2022 at 17:21 Comment(0)
M
0

So if you're trying to do a /$batch OData request like this Microsoft article demonstrates where you're supposed to have a Content-Type header like:

Content-Type: multipart/mixed;boundary=batch_d3bcb804-ee77-4921-9a45-761f98d32029

string headerValue = "multipart/mixed;boundary=batch_d3bcb804-ee77-4921-9a45-761f98d32029";

//You need to set it like thus:
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(headerValue);

Again, the magic you need is: MediaTypeHeaderValue.Parse(...)

Megaspore answered 10/2, 2023 at 1:51 Comment(0)
A
0

Setting the content type (my case I'm setting "application/vnd.api+json") like this worked for me:

var requestBody = new StringContent("{"data": "1"}"), new MediaTypeHeaderValue("application/vnd.api+json"));
var response = await _httpClient.PostAsync(apiUrl, requestBody);
Alithea answered 18/7, 2023 at 19:43 Comment(0)
S
0

By default Content-Type header is forbidden in GET methods, at least in -NET Framework implementation. I solve the problem using a custom Handler that inherits from the one used by HttpClient class. I override the SendAsync method which eliminates that header of the forbidden ones (otherwise you get an exception when you try to add the header to the request), and I include the header when the request has GET method:

public class GetRequestHandler : HttpClientHandler {

public GetRequestHandler(): base() {
}

protected override Task<HttpResponseMessage> SendAsync(
    HttpRequestMessage request, CancellationToken cancellationToken) {

    FieldInfo invalidHeadersField = typeof(HttpHeaders).GetField("invalidHeaders", BindingFlags.NonPublic | BindingFlags.Instance) ?? typeof(HttpHeaders).GetField("_invalidHeaders", BindingFlags.NonPublic | BindingFlags.Instance);
    HashSet<string> invalidHeaders = (HashSet<string>)invalidHeadersField.GetValue(request.Headers);

    invalidHeaders.Remove("Content-Type");

    if(request.Method == HttpMethod.Get) {
        request.Headers.Remove("Content-Type");
        request.Headers.Add("Content-Type", "application/json");
    }
    

    return base.SendAsync(request, cancellationToken);

}

}

Then, in the HttpClient constructor, i use this custom handler:

HttpClient client = new HttpClient(new GetRequestHandler()); 

Doing this, now this works well:

var response = await client.GetAsync(url);
Saturable answered 16/11, 2023 at 17:58 Comment(0)
A
0

Since .NET 5 we can use static JsonContent.Create method. https://docs.microsoft.com/en-us/dotnet/api/system.net.http.json.jsoncontent.create?view=net-5.0

It will set request Content-Type to application/json by default. Strange enough, it allows changing the default type by passing MediaTypeHeaderValue argument.

You can also define JsonSerialization options etc.

The code should look something like this:

var content = JsonContent.Create(new {someData = "data"}, options: new JsonSerializerOptions {PropertyNamingPolicy = JsonNamingPolicy.CamelCase});

or simply:

var content = JsonContent.Create(new {someData = "data"});

if you don't need serializer options or different content type.

Attah answered 9/1 at 14:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.