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

如何按RFC2231规范解析带分段参数的HTTP请求头?

问题

需要按照RFC2231规范解析带分段参数的HTTP请求头,比如下面这个请求头:

Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;
 name*0*=US-ASCII''%D0%97%D0%B0%D0%BF%D1%80%D0%BE%D1%81%20%D0%BF%D1%80%D0;
 name*1*=%B5%D0%B4%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B9%20%D0%BD%D0;
 name*2*=%B0%20%D0%B7%D0%B0%D0%BA%D1%83%D0%BF%D0%BA%D1%83%20#Z_226.xlsx

用以下C#代码解析时:

var ct = new ContentType(headerValueText);
var name = ct.Name;

name返回null,实际和name相关的参数都存在Parameters集合里,键为["name*0*", "name*1*", "name*2*"]。请问该如何正确解析并解码这个name值?

我当前的实现方式如下:

var namesColection = new List<(int position, string value)>();
foreach (DictionaryEntry parametr in ct.Parameters)
{
    if (parametr.Key.ToString().Contains("name"))
    {
        var position = parametr.Key.ToString().Split('*')[1];
        namesColection.Add((int.Parse(position), parametr.Value.ToString()));
    }
}
var nameString = string.Join("", namesColection.OrderBy(p => p.position));
var decodingName = HttpUtility.UrlDecode(nameString.ToString().Split('\'')[2], Encoding.UTF8);
解决方案

你的思路方向是对的,但可以优化细节来适配RFC2231规范,同时处理更多边界情况:

  1. 精准匹配分段参数键:不要只用Contains("name"),应该匹配^name\*\d+\*$的格式,避免误匹配其他带name的参数
  2. 正确解析RFC2231的值格式:每个分段值的格式是[charset]''[encoded-part],其中charset可以省略(默认US-ASCII),所以要正确提取编码部分
  3. 统一解码逻辑:确保使用正确的编码(可从参数中提取charset,而非硬编码UTF8)

优化后的代码示例:

using System.Text.RegularExpressions;

// 收集所有符合规则的name分段参数
var nameSegments = new List<(int Index, string EncodedPart)>();
var segmentPattern = new Regex(@"^name\*(\d+)\*$");

foreach (DictionaryEntry param in ct.Parameters)
{
    var key = param.Key.ToString();
    var match = segmentPattern.Match(key);
    if (match.Success)
    {
        int index = int.Parse(match.Groups[1].Value);
        var valueParts = param.Value.ToString().Split('\'');
        // 提取编码部分:若有三段则取第三段,两段则说明省略了charset取第二段
        string encodedPart = valueParts.Length >=3 ? valueParts[2] : valueParts[1];
        nameSegments.Add((index, encodedPart));
    }
}

// 按索引排序后拼接所有编码片段
var combinedEncoded = string.Join("", nameSegments.OrderBy(s => s.Index));

// 解码:可从第一个有效分段的valueParts[0]获取charset,这里默认用UTF8示例
var decodedName = HttpUtility.UrlDecode(combinedEncoded, Encoding.UTF8);

关键说明:

  • 正则匹配参数键:用^name\*(\d+)\*$确保只匹配name*N*格式的参数,避免误判
  • 值格式处理:RFC2231允许值的格式为charset''encoded或直接encoded(省略charset),所以要判断拆分后的数组长度
  • 编码适配:如果需要严格遵循规范,可以从第一个分段的valueParts[0]获取charset,再对应选择编码类型解码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 00:45:39