You need to enable JavaScript to run this app. C#如何构造适配Open Invoice、带双类型文档与HMAC签名的Multipart/mixed请求
优惠活动
大模型
产品
解决方案
定价
更多

C#如何构造适配Open Invoice、带双类型文档与HMAC签名的Multipart/mixed请求

C#构造符合Open Invoice要求的Multipart/mixed请求方案

针对legacy格式的Multipart/mixed请求、单部分独立设置Content-Type、自定义固定boundary的需求,可以通过手动配置MultipartContent对象、分类设置内容头的方式实现,无需自行拼接整个请求体,可兼容接口格式要求。

具体实现步骤

  • 引入必要命名空间

    实现过程需要用到以下系统命名空间:
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Security.Cryptography;
    using System.Text;
    
  • 构造指定boundary的MultipartContent对象

    按接口要求固定boundary值,同时兼容legacy格式不自动包裹引号:
    // 按接口要求指定固定boundary值
    const string Boundary = "MIME-Boundary";
    // 构造multipart/mixed类型的内容容器
    var multipartContent = new MultipartContent("mixed", Boundary);
    // 移除系统默认给boundary加的双引号,适配legacy接口要求
    multipartContent.Headers.ContentType.Parameters.First(p => p.Name == "boundary").Value = Boundary;
    
  • 分别添加两份文档内容,独立配置每个部分的Content-Type

    每个文档单独构造内容对象,单独指定Content-Type,不会被默认覆盖为text/plain:
    // 1. 添加UTF-8格式的XML部分
    string xmlStr = "你的业务XML字符串内容";
    var xmlPart = new StringContent(xmlStr, Encoding.UTF8);
    // 按接口要求设置XML部分的Content-Type
    xmlPart.Headers.ContentType = MediaTypeHeaderValue.Parse("application/xml; charset=utf-8");
    multipartContent.Add(xmlPart);
    
    // 2. 添加Base64编码的PDF部分
    string base64PdfStr = "你的Base64编码后的PDF内容";
    var pdfPart = new StringContent(base64PdfStr, Encoding.UTF8);
    // 按接口要求设置PDF部分的Content-Type
    pdfPart.Headers.ContentType = MediaTypeHeaderValue.Parse("application/pdf; charset=utf-8");
    multipartContent.Add(pdfPart);
    
  • 生成HMAC签名,构造最终请求

    先读取完整请求体字节流计算签名,再构造请求消息配置校验头:
    // 读取完整请求体字节流用于签名计算
    byte[] requestBodyBytes = await multipartContent.ReadAsByteArrayAsync();
    // 生成HMAC签名,哈希算法、密钥、签名格式按接口实际要求调整,以下为SHA256示例
    string hmacSecret = "你的接口签名密钥";
    string hmacSign;
    using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(hmacSecret)))
    {
        byte[] hashBytes = hmac.ComputeHash(requestBodyBytes);
        hmacSign = Convert.ToBase64String(hashBytes);
    }
    
    // 构造最终请求对象
    var request = new HttpRequestMessage(HttpMethod.Post, "你的Open Invoice接口地址");
    request.Content = multipartContent;
    // 添加签名头,头名按接口实际要求替换
    request.Headers.TryAddWithoutValidation("X-HMAC-Signature", hmacSign);
    
  • 发送请求

    注意HttpClient最好全局实例化复用,不要每次请求新建实例避免端口耗尽问题
    // 示例HttpClient为局部变量,生产环境建议替换为全局单例
    using var client = new HttpClient();
    var response = await client.SendAsync(request);
    // 处理返回结果
    response.EnsureSuccessStatusCode();
    string responseResult = await response.Content.ReadAsStringAsync();
    

常见问题规避

  • Content-Type属于内容头,不要直接添加到HttpRequestMessage.Headers中,否则会抛出无效头异常,需要设置在request.Content.Headers下
  • 如果接口要求boundary必须用双引号包裹,将构造MultipartContent时的boundary值改为"\"MIME-Boundary\""即可
  • HMAC签名计算必须在整个MultipartContent构造完成之后执行,避免内容修改导致签名校验不通过

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 13:45:03