Libin Joseph
Libin Joseph

Reputation: 7342

Custom header to HttpClient request

How do I add a custom header to a HttpClient request? I am using PostAsJsonAsync method to post the JSON. The custom header that I would need to be added is

"X-Version: 1"

This is what I have done so far:

using (var client = new HttpClient()) {
    client.BaseAddress = new Uri("https://api.clickatell.com/");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "xxxxxxxxxxxxxxxxxxxx");
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    var response = client.PostAsJsonAsync("rest/message", svm).Result;
}

Upvotes: 246

Views: 394182

Answers (10)

Sean McNamee
Sean McNamee

Reputation: 116

As many other have stated, take care when setting headers via DefaultRequestHeaders; they'll be used for all requests from the associated HttpClient.

To set headers on a single request, define your headers on a HttpRequestMessage and use the HttpClient.SendAsync method. You can still send objects as JSON using JsonContent.

For the below snippet, assume that I've instantiated my HttpClient with HttpClientFactory with defined DefaultRequestHeaders and a BaseAddress.

using System.Net.Http.Headers;
...

var requestData = new { Foo = "bar" };

var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, "MyEndpointName")
{
    Content = JsonContent.Create(requestData)
};
//Set truly custom headers
httpRequestMessage.Headers.Add("Custom-Header", "Custom-Value");
//Or override headers from `HttpRequestHeaders`
httpRequestMessage.Headers.UserAgent.Add(new ProductInfoHeaderValue(new ProductHeaderValue("Some-User-Agent")));

var response = await _httpClient.SendAsync(httpRequestMessage);

Upvotes: 0

PeterB
PeterB

Reputation: 1206

You can use System.Net.Http.Json.JsonContent, which is what PostAsJsonAsync() does internally:

var jsonContent = JsonContent.Create(payload);
jsonContent.Headers.Add("X-custom-header", "Value");

var resp = await httpClient.PostAsync(uri, jsonContent);

This has advantages above other alternatives:

  • It uses optimized UTF-8 serialization with the applications configured behaviour.
  • It does not set DefaultRequestHeaders, which might affect other, unrelated queries.

Upvotes: 0

Ramil Shavaleev
Ramil Shavaleev

Reputation: 402

Also you can use HttpClient.PostAsync method:

using (HttpClient http_client = new HttpClient())
{
   StringContent string_content = new StringContent(JsonSerializer.Serialize("{\"field\":\"field_value\"}"));
   string_content.Headers.Add("X-Version","1");
   using (HttpResponseMessage response = await http_client.PostAsync("http://127.0.0.1/apiMethodName", string_content))
   {
      if (response.IsSuccessStatusCode)
      {
         Console.WriteLine($"Response status code: {response.StatusCode}");
      }
      else
      {
         Console.WriteLine($"Error status code: {response.StatusCode}");
      }
   }
}

Upvotes: 2

AndyA
AndyA

Reputation: 41

My two cents. I agree with heug. The accepted answer is a mind bender. Let's take a step back.

Default headers apply to all requests made by a particular HttpClient. Hence you would use default headers for shared headers.

_client.DefaultRequestHeaders.UserAgent.ParseAdd(_options.UserAgent);          

However, we sometimes need headers specific to a certain request. We would therefore use something like this in the method:

public static async Task<HttpResponseMessage> GetWithHeadersAsync(this 
    HttpClient httpClient, string requestUri, Dictionary<string, string> headers)
    {
        using (var request = new HttpRequestMessage(HttpMethod.Get, requestUri))
        {
            foreach(var header in headers)
            {
                request.Headers.Add(header.Key, header.Value);
            }

            return await httpClient.SendAsync(request);
        }
    }

If you only need one additional non-default header you would simply use:

request.Headers.Add("X-Version","1")

For more help: How to add request headers when using HttpClient

Upvotes: 4

CCRider
CCRider

Reputation: 11

Just in case someone is wondering how to call httpClient.GetStreamAsync() which does not have an overload which takes HttpRequestMessage to provide custom headers you can use the above code given by @Anubis and call

await response.Content.ReadAsStreamAsync()

Especially useful if you are returning a blob url with Range Header as a FileStreamResult

Upvotes: 0

Aung San Myint
Aung San Myint

Reputation: 191

I have added x-api-version in HttpClient headers as below :

var client = new HttpClient(httpClientHandler)
{
    BaseAddress = new Uri(callingUrl)
};
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("x-api-version", v2);

Upvotes: 3

Chris Peacock
Chris Peacock

Reputation: 4686

Here is an answer based on that by Anubis (which is a better approach as it doesn't modify the headers for every request) but which is more equivalent to the code in the original question:

using Newtonsoft.Json;
...

var client = new HttpClient();
var httpRequestMessage = new HttpRequestMessage
    {
        Method = HttpMethod.Post,
        RequestUri = new Uri("https://api.clickatell.com/rest/message"),
        Headers = { 
            { HttpRequestHeader.Authorization.ToString(), "Bearer xxxxxxxxxxxxxxxxxxx" },
            { HttpRequestHeader.Accept.ToString(), "application/json" },
            { "X-Version", "1" }
        },
        Content = new StringContent(JsonConvert.SerializeObject(svm))
    };

var response = client.SendAsync(httpRequestMessage).Result;

Upvotes: 184

Anubis
Anubis

Reputation: 2614

var request = new HttpRequestMessage {
    RequestUri = new Uri("[your request url string]"),
    Method = HttpMethod.Post,
    Headers = {
        { "X-Version", "1" } // HERE IS HOW TO ADD HEADERS,
        { HttpRequestHeader.Authorization.ToString(), "[your authorization token]" },
        { HttpRequestHeader.ContentType.ToString(), "multipart/mixed" },//use this content type if you want to send more than one content type
    },
    Content = new MultipartContent { // Just example of request sending multipart request
        new ObjectContent<[YOUR JSON OBJECT TYPE]>(
            new [YOUR JSON OBJECT TYPE INSTANCE](...){...}, 
            new JsonMediaTypeFormatter(), 
            "application/json"), // this will add 'Content-Type' header for the first part of request
        new ByteArrayContent([BINARY DATA]) {
            Headers = { // this will add headers for the second part of request
                { "Content-Type", "application/Executable" },
                { "Content-Disposition", "form-data; filename=\"test.pdf\"" },
            },
        },
    },
};

Upvotes: 96

BobTheBuilder
BobTheBuilder

Reputation: 119

There is a Headers property in the HttpRequestMessage class. You can add custom headers there, which will be sent with each HTTP request. The DefaultRequestHeaders in the HttpClient class, on the other hand, sets headers to be sent with each request sent using that client object, hence the name Default Request Headers.

Hope this makes things more clear, at least for someone seeing this answer in future.

Upvotes: 10

Libin Joseph
Libin Joseph

Reputation: 7342

I have found the answer to my question.

client.DefaultRequestHeaders.Add("X-Version","1");

That should add a custom header to your request

Upvotes: 316

Related Questions