37

Where can I set headers to REST service call when using simple HTTPClient?

I do :

HttpClient client = new HttpClient();
var values = new Dictionary<string, string>
{
    {"id", "111"},
    {"amount", "22"}
};
var content = new FormUrlEncodedContent(values);
var uri = new Uri(@"https://some.ns.restlet.uri");

var response = await client.PostAsync(uri, content);
var responseString = await response.Content.ReadAsStringAsync();

UPD

Headers I want to add:

{
    "Authorization": "NLAuth nlauth_account=5731597_SB1, nlauth_email=xxx@xx.com, nlauth_signature=Pswd1234567, nlauth_role=3",
    "Content-Type": "application/json"
}

Should I do the following?

client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", "NLAuth nlauth_account=5731597_SB1, nlauth_email=xxx@xx.com, nlauth_signature=Pswd1234567, nlauth_role=3","Content-Type":"application/json");
themefield
  • 3,847
  • 30
  • 32
vico
  • 17,051
  • 45
  • 159
  • 315
  • Are you looking for this `client.DefaultRequestHeaders.Add("Accept", "application/json");` – Sakis Jun 01 '17 at 16:15
  • What headers you're looking to Add? There are different ways to add different header for example the Accept Header `HttpClient.DefaultRequestHeaders.Accept` – Gururaj Jun 01 '17 at 16:16
  • 1
    Possible duplicate of [Adding headers when using httpClient.GetAsync](https://stackoverflow.com/questions/29801195/adding-headers-when-using-httpclient-getasync) – Juan Carlos Martínez Jun 01 '17 at 16:23
  • See [this answer](https://stackoverflow.com/questions/43158250/how-to-post-using-httpclient-content-type-application-x-www-form-urlencoded/57658305#57658305). – Pedram Aug 26 '19 at 12:57
  • The question is different, but the answer in the original duplicate applies for GET as well and it has more upvotes by a magnitude. – Klesun Aug 08 '23 at 07:43

5 Answers5

47

The way to add headers is as follows:

HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "Your Oauth token");

Or if you want some custom header:

HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("HEADERNAME", "HEADERVALUE");

This answer has SO responses already, see below:

UPDATE

Seems you are adding two headerrs; authorization and content type.

string authValue = "NLAuth nlauth_account=5731597_SB1,nlauth_email=xxx@xx.com, nlauth_signature=Pswd1234567, nlauth_role=3";
string contentTypeValue = "application/json";

client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(authValue);
client.DefaultRequestHeaders.Add("Content-Type", contentTypeValue);
  • I have updated question body with header I need to add. I suppose I should use Authorization header? – vico Jun 02 '17 at 07:07
  • Check the answer from Alaa Masoud here: https://stackoverflow.com/questions/19039450/adding-authorization-to-the-headers for more details. – Juan Carlos Martínez Jun 03 '17 at 15:02
  • Microsoft docs [advise](https://learn.microsoft.com/en-us/azure/architecture/antipatterns/improper-instantiation/) `HttpClient` to be a singleton unless you have a very good reason for it not to be. I wonder if the "Default" part of the "DefaultRequestHeaders" implies that headers can also be supplied on a per-request basis without mutating state of the client... – Klesun Aug 08 '23 at 06:41
13

I know this was asked a while ago, but Juan's solution didn't work for me.

(Also, pretty sure this question is duplicated here.)

The method that finally worked was to use HttpClient with HttpRequestMessage and HttpResponseMessage.

Also note that this is using Json.NET from Newtonsoft.

    using System;
    using System.Net.Http;
    using System.Text;
    using System.Threading.Tasks;
    using System.Net.Http.Headers;
    using Newtonsoft.Json;

    namespace NetsuiteConnector
    {
        class Netsuite
        {

            public void RunHttpTest()
            {
                Task t = new Task(TryConnect);
                t.Start();
                Console.WriteLine("Connecting to NS...");
                Console.ReadLine();
            }

            private static async void TryConnect()
            {
                // dummy payload
                String jsonString = JsonConvert.SerializeObject(
                    new NewObj() {
                        Name = "aname",
                        Email = "someone@somewhere.com"
                    }
                );

                string auth = "NLAuth nlauth_account=123456,nlauth_email=youremail@somewhere.com,nlauth_signature=yourpassword,nlauth_role=3";

                string url  = "https://somerestleturl";
                var uri     = new Uri(@url);

                HttpClient c = new HttpClient();
                    c.BaseAddress = uri;
                    c.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", auth);
                    c.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, url);
                req.Content = new StringContent(jsonString, Encoding.UTF8, "application/json");

                HttpResponseMessage httpResponseMessage = await c.SendAsync(req);
                httpResponseMessage.EnsureSuccessStatusCode();
                HttpContent httpContent = httpResponseMessage.Content;
                string responseString = await httpContent.ReadAsStringAsync();

                Console.WriteLine(responseString);
            }
        }

        class NewObj
        {
            public string Name { get; set; }
            public string Email { get; set; }
        }
    }
Sundance.101
  • 404
  • 3
  • 10
4

The other answers do not work if you are using an HttpClientFactory, and here's some reasons why you should. With an HttpClientFactory the HttpMessages are reused from a pool, so setting default headers should be reserved for headers that will be used in every request.

If you just want to add a content-type header you can use the alternate PostAsJsonAsync or PostAsXmlAsync.

var response = await _httpClient.PostAsJsonAsync("account/update", model);

Unfortunately I don't have a better solution for adding authorization headers than this.

_httpClient.DefaultRequestHeaders.Add(HttpRequestHeader.Authorization.ToString(), $"Bearer {bearer}");
Red
  • 3,030
  • 3
  • 22
  • 39
3

On dotnet core 3.1 trying to run the top answer:

HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Content-Type", "application/x-msdownload");

threw an exception: System.InvalidOperationException: Misused header name. Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects.

What worked for me was to instead set HttpContent.Headers -> HttpContentHeaders.ContentType property with a MediaTypeHeaderValue value:

HttpClient client = new HttpClient();
var content = new StreamContent(File.OpenRead(path));
content.Headers.ContentType = new MediaTypeHeaderValue("application/x-msdownload");
var post = client.PostAsync(myUrl, content);
Carl Walsh
  • 6,100
  • 2
  • 46
  • 50
2

I prefer to cache the httpClient so I avoid setting headers which could affect other requests and use SendAsync()

var postRequest = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post, url);
postRequest.Headers.Add("Authorization", "NLAuth nlauth_account=5731597_SB1, nlauth_email=xxx@xx.com, nlauth_signature=Pswd1234567, nlauth_role=3");

var response = await httpClient.SendAsync(postRequest);
var responseString = await response.Content.ReadAsStringAsync();

Note, the Content-Type: application/json header would conflict with the FormUrlEncodedContent() used in your code sample, as it already adds the Content-Type: application/x-www-form-urlencoded header.

Klesun
  • 12,280
  • 5
  • 59
  • 52
iasksillyquestions
  • 5,558
  • 12
  • 53
  • 75