调用 HTTPClient.PostAsync 时设置授权/内容类型标头

问题描述 投票:0回答:6

使用简单 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();

UPD

我要添加的标题:

{
    "Authorization": "NLAuth nlauth_account=5731597_SB1, [email protected], nlauth_signature=Pswd1234567, nlauth_role=3",
    "Content-Type": "application/json"
}

我应该执行以下操作吗?

client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", "NLAuth nlauth_account=5731597_SB1, [email protected], nlauth_signature=Pswd1234567, nlauth_role=3","Content-Type":"application/json");
c# netsuite
6个回答
47
投票

添加表头的方法如下:

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

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

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

这个答案已经有这样的回应,见下文:

更新

似乎您要添加两个标头;授权和内容类型。

string authValue = "NLAuth nlauth_account=5731597_SB1,[email protected], nlauth_signature=Pswd1234567, nlauth_role=3";
string contentTypeValue = "application/json";

client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(authValue);
client.DefaultRequestHeaders.Add("Content-Type", contentTypeValue);

13
投票

我知道不久前有人问过这个问题,但胡安的解决方案对我不起作用。

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

最终有效的方法是将 HttpClient 与 HttpRequestMessageHttpResponseMessage 一起使用。

另请注意,这是使用 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 = "[email protected]"
                    }
                );

                string auth = "NLAuth nlauth_account=123456,[email protected],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; }
        }
    }

4
投票

如果您使用 HttpClientFactory,其他答案将不起作用,并且 这里有一些原因 为什么您应该这样做。使用 HttpClientFactory,HttpMessage 可以从池中重用,因此应为每个请求中使用的标头保留设置默认标头。

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

PostAsJsonAsync
PostAsXmlAsync

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

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

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

3
投票

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

2
投票

更喜欢缓存httpClient,这样我就可以避免设置可能影响其他请求的标头并使用SendAsync

            var postRequest = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, url);
            postRequest.Headers.Add("Content-Type", "application/x-msdownload");

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

0
投票

如果您不想在每个具有自定义标头的请求上创建

HttpClient
的新实例,这里有一个使用new HttpRequestMessage()的解决方案,让您可以在每个请求的基础上指定标头,而无需改变
HttpClient
实例:

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

// changes here
var request = new HttpRequestMessage(HttpMethod.Post, uri);
request.Headers.Add("Authorization", "NLAuth nlauth_account=5731597_SB1, [email protected], nlauth_signature=Pswd1234567, nlauth_role=3");
var response = await client.SendAsync(request);

var responseString = await response.Content.ReadAsStringAsync();

注意,

Content-Type: application/json
标头会与代码示例中使用的
FormUrlEncodedContent()
冲突,因为它已经添加了
Content-Type: application/x-www-form-urlencoded
标头。

© www.soinside.com 2019 - 2024. All rights reserved.