如何在使用HttpClient的GET方法中设置content-md5头?

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

我有下面的代码在我的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请求头中设置。

下面是图片

enter image description here

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

从阅读 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改变代码,它可能会崩溃) 。


-1
投票

除了用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请求中发送内容会导致错误。

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