调用 HTTPClient.PostAsync 时设置 Authorization/Content-Type 标头

Posted

技术标签:

【中文标题】调用 HTTPClient.PostAsync 时设置 Authorization/Content-Type 标头【英文标题】:Set Authorization/Content-Type headers when call HTTPClient.PostAsync 【发布时间】:2017-06-01 16:08:00 【问题描述】:

在使用简单 HTTPClient 时,我可以在哪里设置 REST 服务调用的标头?

我愿意:

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();

更新

我要添加的标题:


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

我应该执行以下操作吗?

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");

【问题讨论】:

你在找这个client.DefaultRequestHeaders.Add("Accept", "application/json"); 您要添加哪些标题?有不同的方法可以添加不同的标题,例如 Accept Header HttpClient.DefaultRequestHeaders.Accept Adding headers when using httpClient.GetAsync的可能重复 见this answer。 【参考方案1】:

添加表头的方法如下:

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

或者如果你想要一些自定义标题:

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

这个答案已经有 SO 响应了,见下文:

Adding headers when using httpClient.GetAsync Setting Authorization Header of HttpClient

更新

似乎您正在添加两个标题;授权和内容类型。

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);

【讨论】:

我已经用需要添加的标题更新了问题正文。我想我应该使用 Authorization 标头? 查看 Alaa Masoud 的答案:***.com/questions/19039450/… 了解更多详情。【参考方案2】:

我知道这是不久前被问到的,但 Juan 的解决方案对我不起作用。

(另外,很确定这个问题是重复的here。)

最终奏效的方法是使用带有HttpRequestMessage 和HttpResponseMessage 的HttpClient。

另请注意,这是使用来自 Newtonsoft 的 Json.NET。

    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; 
        
    

【讨论】:

【参考方案3】:

如果您使用的是 HttpClientFactory,则其他答案不起作用,here's some reasons 为什么应该这样做。使用 HttpClientFactory,可以从池中重用 HttpMessage,因此应为每个请求中使用的标头保留设置默认标头。

如果您只想添加内容类型标头,可以使用备用PostAsJsonAsyncPostAsXmlAsync

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

不幸的是,我没有比这更好的添加授权标头的解决方案了。

_httpClient.DefaultRequestHeaders.Add(HttpRequestHeader.Authorization.ToString(), $"Bearer bearer");

【讨论】:

【参考方案4】:

在 dotnet core 3.1 上尝试运行最佳答案:

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

抛出异常:System.InvalidOperationException: Misused header name. Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects.

对我有用的是将 HttpContent.Headers -> HttpContentHeaders.ContentType 属性设置为 MediaTypeHeaderValue 值:

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);

【讨论】:

以上是关于调用 HTTPClient.PostAsync 时设置 Authorization/Content-Type 标头的主要内容,如果未能解决你的问题,请参考以下文章

异步等待 HttpClient.PostAsync 调用

如何等待PostAsync返回?

HttpClient PostAsync 发布空内容

网络条件差时如何处理文件HttpClient.PostAsync文件上传?

使用 Blazor 和 Aspnet Webapi 跟踪 HttpClient.PostAsync 进度

C# HttpClient PostAsync 将 204 变成 404