在 .Net 中的 httpClient 中单独发送相同的密钥标头

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

我需要发送带有自定义标头列表的 HTTP 请求。这些标头可能具有具有不同值的重复键。我正在从事 .NET Framework 项目。

到目前为止,我已经尝试使用 HttpClient 并添加相同的关键标头:

using (var client = new HttpClient())
{
    var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:8080/api/test");
    request.Headers.Add("Set-Cookie", "key1=value1; key2=value2; Path=/;");
    request.Headers.Add("Another-Key", "value1");
    request.Headers.Add("Set-Cookie", "key3=value3; Path=/;"); 
    await client.SendAsync(request);
}

注意:它不必像示例中那样专门是

Set-Cookie
标头,它可以是任何重复的标头键。

但是在服务器端读取这些标头时,标头值显示为用逗号连接和分隔的不同值:

Set-Cookie:key1=value1; key2=value2; Path=/;, key3=value3; Path=/;

而且我特别希望服务器端接收一组值,所以应该是

"Set-Cookie": ["key1=value1; key2=value2; Path=/;","key3=value3; Path=/;"]

服务器端所需的行为可以通过 CURL 请求来实现:

curl --location 'http://localhost:8080/api/test' --header 'Set-Cookie: key1=value1; key2=value2; Path=/;' --header 'Another-Key: value1' --header 'Set-Cookie: key3=value3; Path=/;'

但是我无法为 .NET 请求标头复制这种类型的行为。我也尝试过使用

WebClient
HttpWebRequest
,但这两个都生成了单个逗号分隔的字符串。

有没有办法将具有不同值的多个相同键标头作为值数组发送,而不是发送多个值的单个连接字符串?

编辑:

对于服务器端测试,使用

IHttpContextAccessor
接口。它被注入到用于测试和读取标头的服务中。

var headers = _httpContextAccessor.HttpContext.Request.Headers;

问题是,出于生产目的,将使用第三方服务器,并且不能以任何方式对其进行修改,并且它特别需要相同密钥标头的值数组。

c# .net http dotnet-httpclient .net-4.8
1个回答
0
投票

TL;DR:

HttpRequestMessage
HttpRequest
是不同的。


每当您创建

HttpClient
请求时,您都在使用
HttpRequestMessage
对象。

var req = new HttpRequestMessage(HttpMethod.Get, "http://test.com")
{
    Headers =
    {
        { "A", "A" },
        { "A", "B" }
    }
};

上面的代码完全没问题,因为

Headers
属性定义为
HttpRequestHeaders
,它派生自
HttpHeaders
类:

public abstract class HttpHeaders : IEnumerable<KeyValuePair<string,IEnumerable<string>>>

如您所见,它被定义为一系列键值对,其中键是一个字符串,值是一系列字符串。


每当您访问

Request
HttpContext
时,您就不会使用
HttpRequestMessage
类型,而不是
HttpRequest

HttpRequest
Headers
属性被定义为
NameValueCollection
,它派生自
NameObjectCollectionBase
类:

public abstract class NameObjectCollectionBase : ICollection, IDeserializationCallback, ISerializable

正如文档强调的那样

为关联的

String
键和
Object
值的集合提供抽象基类,可以使用键或索引访问

该值是单个对象,而不是一系列对象。因此,以下代码将产生

ArgumentException
已添加具有相同键的项目):

var httpContext = new DefaultHttpContext();
httpContext.Request.Headers.Add("A", "A");
httpContext.Request.Headers.Add("A", "B");

为了支持同一键的多个值,微软只是将这些值用字符串连接起来。这也是你的实验所验证的。

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