我有下面的代码在我的GET方法请求中设置content-md5头。HttpClient
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("content-md5", "value");
我不能用 HttpRequestMessage 内容来设置,因为它不是POST方法。当使用 邮递员 它工作得很好,但当使用 HttpClient.GetAsync
.客户端向服务器请求一个hmac,如下所示
{
"content_to_hash": "my content"
}
服务器会给出这样的响应
{
"content_md5": "88af7ceab9fdafb76xxxxx",
"date": "Sat, 02 May 2020 00:13:16 +0700",
"hmac_value": "WfHgFyT792IENmK8Mqz9LysmP8ftOP00qA="
}
现在我必须使用那个hmac访问一个GET请求,问题就出在这里,因为我不能在httpClient的GET请求头中设置。
下面是图片
从阅读 HttpClient
和相关的源代码,你没有办法绕过这一点,把头添加到实际的请求对象头中。有一个无效头文件的内部列表,其中包括任何的 Content-*
头文件。它必须在一个内容对象上。
因此,我建议的解决方案是创建你自己的内容对象。
public class NoContentMd5 : HttpContent
{
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
return Task.CompletedTask;
}
protected override bool TryComputeLength(out long length)
{
length = 0;
return false;
}
public NoContentMd5(byte[] contentMd5)
{
this.Headers.ContentMD5 = contentMd5;
}
public NoContentMd5(string contentMd5)
{
this.Headers.TryAddWithoutValidation("Content-MD5", contentMd5);
}
}
这将增加 Content-MD5
头,但请求不会包含body。
你会遇到的下一个问题是,你正试图发出一个带有内容的GET请求,而这个请求并不被辅助程序 client.GetAsync(...)
方法。你必须创建你自己的请求对象,并使用 client.SendAsync(...)
来代替。
HttpClient client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://localhost/my/test/uri");
request.Content = new NoContentMd5("d41d8cd98f00b204e9800998ecf8427e ");
var result = await client.SendAsync(request);
请注意,如果你的Content-MD5哈希值是字节数,我还为你的内容添加了一个构造函数。NoContentMd5
对于 byte[]
也。
唯一的潜在问题是,它包括了一个。Content-Length: 0
头。希望你所使用的API可以做到这一点。
有一个替代的解决方案描述在 本回答 的问题。我反对使用它,因为它很容易受到实现细节的变化的影响 HttpRequestHeaders
(因为它使用反射,所以如果MS改变代码,它可能会崩溃) 。
除了用GET请求发送body被认为不是一个好的做法之外(参见 HTTP GET,请求体为),你可以试试这个。
using (var content = new StringContent(string.Empty))
using (var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("http://localhost"),
Content = content
})
{
request.Headers.TryAddWithoutValidation("content-md5", "value");;
using (var response = await httpClient.SendAsync(request))
{
response.EnsureSuccessStatusCode();
}
}
UPDATE:
正确的方法应该是将 ContentMD5
上的财产 HttpContentHeaders
比如说,你可以用GET请求来发送内容。
content.Headers.ContentMD5 = Convert.FromBase64String(hashString);
但正如你在评论中指出的那样,试图在GET请求中发送内容会导致错误。