【问题标题】:Custom header to HttpClient requestHttpClient 请求的自定义标头
【发布时间】:2016-06-24 18:36:22
【问题描述】:

如何向HttpClient 请求添加自定义标头?我正在使用PostAsJsonAsync 方法发布 JSON。我需要添加的自定义标题是

"X-Version: 1"

这是我到目前为止所做的:

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

【问题讨论】:

标签: c# asp.net http-headers dotnet-httpclient


【解决方案1】:

我找到了问题的答案。

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

这应该为您的请求添加一个自定义标头

【讨论】:

  • 不,它没有。应谨慎查看此答案,因为默认请求标头随每个请求一起发送。您应该像@Anubis 建议的那样构建您的请求。创建 HttpClient 时应填充 DefaultsRequestHeaders。
  • 这仅适用于您为每个请求实例化一个新的 HttpClient。这不是这个类的使用方式:它应该是一个静态字段,对所有请求重用,至少对同一端点的请求重用。查看文档和无数的博客文章。然后,当然,正如@Ruhrpottpatriot 指出的那样,更改默认标头将影响所有请求。
  • @ajbeaven 不,这不是它所说的。页面顶部的示例显示了应用程序的 Main 方法,因此即使处理了 HttpClient ,在应用程序的整个生命周期中都会使用相同的实例,这对于文档所说的内容是正确的再往下一点:'HttpClient 旨在被实例化一次并在应用程序的整个生命周期中重复使用'。本段后面是一个建议将 HttpClient 分配给静态字段的示例。
  • @kamilk,你说得对 - 这个例子让我错了。谢谢你把我说对了:)
  • 如果您使用HttpClientFactory 实例化httpclient,可以使用这个答案吗?
【解决方案2】:

这是基于 Anubis 的答案(这是一种更好的方法,因为它不会修改每个请求的标头),但它更等同于原始问题中的代码:

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;

【讨论】:

  • @RossPresser 绝对不是。 Content-Type 是一个内容标头。
  • 同意这是答案。它演示了如何添加 OP 请求的标头。也回答了我的问题。
  • 仅供参考,我认为HttpRequestHeader.Access 应该是HttpRequestHeader.Accept
  • 顺便问一下什么是svm?
  • @aswzen 这是来自 OP 的问题 - 我猜是模型。正在序列化的对象。
【解决方案3】:
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\"" },
            },
        },
    },
};

【讨论】:

  • 答案非常令人困惑......为什么要引入文档代码,blank.pdf 等?实例化 bytearray 类以在 Content 参数中传递自定义标头?
  • @heug 好吧。如果您正在寻找标题,您可以看到它。此处显示的内容是为了完成图片,因为您很可能希望在请求中添加一些内容。而且为了不乏味,内容很复杂,包含 JSON 和二进制数据。
  • 这样做似乎更直接:使用您的内容 JSON 创建 StringContent,使用您的方法和 URI 创建一个 HTTP 消息,然后添加诸如 message.Headers.Add("x": "y") .... 然后将它们传递到响应变量中,例如 "var response = await httpClient.SendAsync(message);"
  • 上述接受的答案中的哪一行实际上实现了 OP 请求的标头,X-Version?为什么这被认为是公认的答案?
  • 我发现这个答案真的很有帮助,感谢您提供额外的示例。
【解决方案4】:

HttpRequestMessage 类中有一个 Headers 属性。您可以在那里添加自定义标头,这些标头将随每个 HTTP 请求一起发送。另一方面,HttpClient 类中的 DefaultRequestHeaders 设置使用该客户端对象发送的每个请求的标头,因此名称为 Default 请求标头。

希望这能让事情更清楚,至少对于将来看到这个答案的人来说。

【讨论】:

  • 不,没有让它更清楚。在这两种情况下,您都说您在每个请求上都发送标头 - 那么有什么区别?
  • Headers 是单个 HttpRequestMessage 对象的属性。因此,您可以创建具有不同标题的不同消息。 DefaultRequestHeadersHttpClient 对象的属性;如果通过给定的HttpClient 发送多条消息,则所有此类消息都将在消息的各个标头中添加相同的DefaultRequestHeaders
【解决方案5】:

我在 HttpClient 标头中添加了 x-api-version,如下所示:

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

【讨论】:

    【解决方案6】:

    以防万一有人想知道如何调用 httpClient.GetStreamAsync() ,它没有使用 HttpRequestMessage 提供自定义标头的重载,您可以使用@Anubis 给出的上述代码并调用

    await response.Content.ReadAsStreamAsync()

    如果您要返回带有 Range Header 作为 FileStreamResult 的 blob url,则特别有用

    【讨论】:

      【解决方案7】:

      我的两分钱。我同意heug。公认的答案令人费解。让我们退后一步。

      默认标头适用于特定 HttpClient 发出的所有请求。因此,您将为共享标头使用默认标头。

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

      但是,我们有时需要特定于某个请求的标头。因此,我们会在方法中使用类似这样的东西:

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

      如果您只需要一个额外的非默认标头,您只需使用:

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

      更多帮助: How to add request headers when using HttpClient

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-21
        • 2014-08-08
        • 2013-11-13
        相关资源
        最近更新 更多