调用HTTPClient.PostAsync时设置Authorization/Content-Type头
调用HTTPClient.PostAsync时设置Authorization/Content-Type头
当使用简单的HTTPClient时,我可以在哪里设置REST服务调用的头信息?
我这样做:
HttpClient client = new HttpClient(); var values = new Dictionary{ {"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");
问题的出现原因是使用HttpClientFactory时,无法直接设置授权和内容类型的请求头。这是因为HttpClientFactory会从一个连接池中重用HttpMessage实例,所以默认请求头应该保留给每个请求都会使用的请求头。
解决方法是使用PostAsJsonAsync或PostAsXmlAsync方法来添加内容类型请求头。例如,可以使用以下代码来添加一个内容类型为Json的请求头:
var response = await _httpClient.PostAsJsonAsync("account/update", model);
不幸的是,目前没有更好的解决方法来添加授权请求头。一个可能的解决办法是使用以下代码来添加授权请求头:
_httpClient.DefaultRequestHeaders.Add(HttpRequestHeader.Authorization.ToString(), $"Bearer {bearer}");
这样可以将一个名为Authorization的请求头添加到所有请求中,值为"Bearer {bearer}",其中{bearer}是授权令牌的值。
问题出现的原因是Juan的解决方案对我无效,并且这个问题可能是重复的,可以在这里找到更多关于这个的问题。
最终有效的解决方法是使用HttpClient与HttpRequestMessage和HttpResponseMessage。同时,这个方法使用了来自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.com" } ); string auth = "NLAuth nlauth_account=123456,nlauth_email=youremail.com,nlauth_signature=yourpassword,nlauth_role=3"; string url = "https://somerestleturl"; var uri = new Uri(); 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; } } }
解决方法是在发送请求之前设置HttpClient的Authorization和Content-Type头。
问题的出现原因是:用户想要在调用HTTPClient.PostAsync方法时设置Authorization和Content-Type头部。
解决方法是:通过以下方式添加头部:
HttpClient client = new HttpClient(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "Your Oauth token");
或者如果想要添加自定义头部:
HttpClient client = new HttpClient(); client.DefaultRequestHeaders.Add("HEADERNAME", "HEADERVALUE");
用户还可以参考以下链接获取更多关于添加头部的信息:
- [Adding headers when using httpClient.GetAsync](https://stackoverflow.com/questions/29801195)
- [Setting Authorization Header of HttpClient](https://stackoverflow.com/questions/14627399)
用户还提到了需要添加两个头部:authorization和content type。可以通过以下代码实现:
string authValue = "NLAuth nlauth_account=5731597_SB1,nlauth_email=xxx.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在这里的答案获取更多细节:[adding authorization to the headers](https://stackoverflow.com/questions/19039450)
另外,Microsoft的文档建议将HttpClient作为单例使用,除非有非常好的理由不这样做。用户还想知道"DefaultRequestHeaders"中的"Default"是否意味着头部也可以在每个请求中单独提供,而不需要改变客户端的状态。