.NET Core使用HttpClient进行表单提交时遇到的问题 |
|
问题# 在开发微信支付的小微商户进件接口时,需要通过表单来上传身份证图片等数据 。在微信支付接口文档也说明了,需要使用 multipart/form-data 的方式发送请求 。.NET 提供了 MultipartFormDataContent 类型,帮助我们构建表单请求,故有以下代码:
var form = new MultipartFormDataContent()
{
{new StringContent("Value"),"Name},
{new ByteArrayContent(new byte[]{}/*模拟文件数据*/),"File,"FileName}
}
按照微信支付官方文档提交之后,一直提示参数错误,百思不得其解 。 原因# 通过 Postman 模拟表单提交,捕获数据包,将其与 C# 的提交代码进行对比,发现了两处问题 。 Postman 的原始提交:
C# 代码的提交:
1. Boundary 的双引号 使用 MultipartFormDataContent 提交的表单请求,外部 Content-Type 的 boundary 值带有 " 号 。而 Postman 提交的表单请求,它的 boudary 值是没有双引号的 。 那为什么会造成这样的差异呢?参考 这篇 博客的讲解,是由于各个系统/语言针对 RFC 2046 的实现不一致导致的 。针对于 MultipartFormDataContent 的行为,如果 Boundary 后面的值带有双引号是符合标准的 。
Boundary 的作用,是一个随机生成的字符串,在 HTTP 协议当中用于分割内部多个 Content 。为什么是随机生成的呢?就是防止这个分割符跟你内部的 Content 产生重复造成意外 。(C# 默认使用的是 Guid 作为随机串,你也可以在构造 MultipartFormDataContent 的时候,通过其构造函数手动指定) 2. 表单内键值对,值的双引号 第二个问题则是表单内的内容,他们的 name 键值对,其值又没有双引号,所以你得在添加 Content 的时候,得手动指定双引号 。 解决# 两个问题都是由于双引号导致的,所以只需要在真正发起调用之前将内部的双引号替换为空,或者将缺失的双引号添加上即可 。 针对问题一,其内部的 ContentType.Parameters ,通过 LINQ 找到 boundary 的键值对,替换内部的双引号即可 。
var boundaryValue = form.Headers.ContentType.Parameters.Single(p => p.Name == "boundary");
boundaryValue.Value = boundaryValue.Value.Replace(""", String.Empty);
针对问题二,在构造内部 Content 的时候,其 Name 手动赋予双引号 。
var form = new MultipartFormDataContent
{
{new StringContent(mchId), ""mch_id""},
{new ByteArrayContent(bytes), "media", $""{HttpUtility.UrlEncode(Path.GetFileName(imagePath))}""},
{new StringContent(mediaHash), ""media_hash""},
{new StringContent(sign), "sign"}
};
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家 。 |