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

.NET 6中如何将HttpClient请求体提取为键值对集合?

解决方案

1. 先处理请求体流的重置问题

读取请求体后必须重置流位置,否则后续请求会因流已耗尽而失败:

var bodyString = await request.Content.ReadAsStringAsync();
// 重置流,保证后续请求能正常读取
var contentBytes = Encoding.UTF8.GetBytes(bodyString);
request.Content = new ByteArrayContent(contentBytes);
request.Content.Headers.ContentType = request.Content.Headers.ContentType;

2. 解析请求体为键值对集合

根据请求体的Content-Type分场景处理:

场景一:表单编码(application/x-www-form-urlencoded)

直接利用FormUrlEncodedContent的原生方法解析:

if (request.Content.Headers.ContentType?.MediaType == "application/x-www-form-urlencoded")
{
    var formContent = request.Content as FormUrlEncodedContent;
    if (formContent != null)
    {
        var bodyKvp = await formContent.ReadAsNameValueCollectionAsync();
        // 转换为List<KeyValuePair>方便后续排序
        var bodyPairs = bodyKvp.AllKeys.Select(key => new KeyValuePair<string, string>(key, bodyKvp[key])).ToList();
    }
}

场景二:JSON格式(application/json)

用JSON解析库将字符串转成字典,再转成键值对集合:

if (request.Content.Headers.ContentType?.MediaType == "application/json")
{
    // 使用System.Text.Json
    var bodyDict = JsonSerializer.Deserialize<Dictionary<string, object>>(bodyString);
    var bodyPairs = bodyDict?.ToList() ?? new List<KeyValuePair<string, object>>();
    
    // 若API要求展开嵌套JSON,需递归处理字段(示例)
    // var flattenedPairs = FlattenJson(bodyDict);
}

// 若使用Newtonsoft.Json,替换为:
// var bodyDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(bodyString);

场景三:表单上传(multipart/form-data)

仅提取非文件的文本字段(一般API签名不包含文件内容):

if (request.Content.Headers.ContentType?.MediaType == "multipart/form-data")
{
    var multipartContent = request.Content as MultipartFormDataContent;
    if (multipartContent != null)
    {
        var bodyPairs = new List<KeyValuePair<string, string>>();
        foreach (var content in multipartContent)
        {
            var fieldName = content.Headers.ContentDisposition?.Name?.Trim('"');
            if (fieldName != null && content is StringContent stringContent)
            {
                var fieldValue = await stringContent.ReadAsStringAsync();
                bodyPairs.Add(new KeyValuePair<string, string>(fieldName, fieldValue));
            }
        }
    }
}

3. 合并头部与请求体并生成签名串

统一处理头部和请求体的键值对,按ASCII排序后拼接:

// 处理头部:将多值表头转为单个字符串(按API要求选择拼接规则)
var processedHeaders = headers.Select(h => new KeyValuePair<string, string>(h.Key, string.Join(",", h.Value))).ToList();

// 合并头部与请求体的键值对
var allPairs = processedHeaders.Concat(bodyPairs).ToList();

// 按键的ASCII顺序排序
var sortedPairs = allPairs.OrderBy(p => p.Key, StringComparer.Ordinal).ToList();

// 拼接成签名字符串(示例格式:key1=value1&key2=value2)
var signatureString = string.Join("&", sortedPairs.Select(p => $"{p.Key}={p.Value}"));

注意:需根据对接API的要求,排除不需要参与签名的头部字段(如Authorization、Content-Length),或对值做URL编码等额外处理。

内容的提问来源于stack exchange,提问作者Ramy.is.here

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 14:27:23