You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Azure表存储中用System.Net.Http.HttpClient正确设置ContentMD5属性

我帮你排查了问题,发现有两个关键问题需要解决:一个是代码里的请求方法不匹配,另一个是跨平台下HttpClient对Content-MD5头的处理差异。下面是具体的修复方案和解释:

首先,修正请求发送的代码错误

你当前创建了PUT方法的HttpRequestMessage,但完全没用到它,反而调用PostAsync发送了POST请求——这会导致你设置的所有请求配置都失效,包括Content-MD5头。先把这部分代码修正过来:

string contentString = "<some xml content>";

// 统一MD5计算逻辑(确保跨平台一致)
System.Security.Cryptography.MD5CryptoServiceProvider csp = new MD5CryptoServiceProvider();
var hash = csp.ComputeHash(Encoding.UTF8.GetBytes(contentString));
var hashString = ByteArrayToString(hash); // 得到和之前一致的十六进制字符串

// 初始化HttpClient和请求消息
System.Net.Http.HttpClient client = new HttpClient();
Uri uri = new Uri("http://woschmi01.table.core.windows.net/Test2018()");
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Put, uri);
var content = new StringContent(contentString);

// 添加Content-MD5头到内容头
content.Headers.Add("Content-MD5", hashString);
requestMessage.Content = content;

// 发送请求
var response = await SendRequest(client, requestMessage);

// 修正后的SendRequest方法
async Task<HttpResponseMessage> SendRequest(HttpClient client, HttpRequestMessage requestMessage)
{
    HttpResponseMessage response = await client.SendAsync(requestMessage);
    return response;
}

// 确保十六进制字符串格式统一(大写、无连字符)
static string ByteArrayToString(byte[] ba)
{
    return BitConverter.ToString(ba).Replace("-", "").ToUpperInvariant();
}

解决iOS上Content-MD5头为空的问题

iOS平台的HttpClient底层依赖NSURLSession,它会自动管理部分标准HTTP头(包括Content-MD5),直接用content.Headers.Add添加的头可能被过滤掉。这里给你两个可行的解决方案:

方案1:自定义消息处理程序(跨平台兼容)

创建一个自定义的消息处理程序,强制保留你添加的Content-MD5头,绕过系统的自动过滤:

public class ContentMd5PreserveHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (request.Content != null)
        {
            // 检查是否已设置Content-MD5头
            var md5Header = request.Content.Headers.FirstOrDefault(h => 
                h.Key.Equals("Content-MD5", StringComparison.OrdinalIgnoreCase));
            
            if (md5Header.Value != null && md5Header.Value.Any())
            {
                // 先移除可能被系统处理的头,再重新添加(强制保留)
                request.Content.Headers.Remove("Content-MD5");
                request.Content.Headers.TryAddWithoutValidation("Content-MD5", md5Header.Value.First());
            }
        }
        
        return await base.SendAsync(request, cancellationToken);
    }
}

// 初始化HttpClient时使用这个处理程序
var handler = new ContentMd5PreserveHandler();
handler.InnerHandler = new HttpClientHandler();
System.Net.Http.HttpClient client = new HttpClient(handler);

方案2:直接添加到请求头(简化版)

如果自定义处理程序太复杂,可以尝试把Content-MD5头添加到请求的Headers中(虽然严格来说它属于内容头,但Azure表存储通常会接受这种方式):

// 替换原来的content.Headers.Add,改成添加到请求消息的Headers
requestMessage.Headers.Add("Content-MD5", hashString);

额外验证:确保哈希值跨平台一致

为了避免MD5计算结果不一致,要注意两个细节:

  • 确保contentString的编码是UTF-8,且没有额外的BOM(字节顺序标记)
  • ByteArrayToString方法要统一返回大写的十六进制字符串(添加.ToUpperInvariant(),避免大小写差异导致认证失败)

这样调整后,UWP和iOS平台的请求都会包含和之前一致的Content-MD5头,Fiddler里能看到正确的值,SharedKey认证也能正常通过。

内容的提问来源于stack exchange,提问作者Roland Schmidt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:51:05