.NET Core使用HttpClient进行表单提交时遇到的问题_实用技巧

来源:脚本之家  责任编辑:小易  

什么是 ASP.NET Core?ASP.NET Core 1.0 是一个开源跨平台的开发框架,用于构建基于云的现代 Web 应用。它是从底层开始重新构建来提供性能优良的Web应用开发框架,可以部署在云上或者本地服务器上。另外,它使得 ASP.NET 应用更加精简和模块化(可以根据你的应用需要向里面添加其他模块),跨平台(你可以很容易的在 Windows,Mac or Linux 上开发和部署你的应用),云优化(你可以在云上在云上部署和调试你的应用)。以前的版本对于使用 ASP.NET 旧版本的我们来说,这意味着什么?如果你正在使用旧版本的 ASP.NET 或者你有 WebForms 的开发背景,那么你将会认识到 ASP.NET Core 有多完美,这感觉起来就像从古典的 ASP 时代来到全新的 ASP.NET 的世界。现在,让我们来一探究竟下面列出 ASP.NET Core 1.0 的核心变化.跨平台的运行时你可以在 OSX 和 Linux上运行 ASP.NET Core 应用,这对于 ASP.NET 来说,这具有跨时代的意义,也给 ASP.NET 开发者和设计师们带来了全新的体验。ASP.NET Core 具有两个运行时,这意味着你可以选择不同的运行环境来部署你的应用,使得你的应用将更加灵活。ASP.NET Core 1.0 是一个 ASP.NET 的重构版本,它运行于最新的.NET Core。它是模块化的,允许开发者以插件的形式添加应用所需要的模块,大多数的功能都将作为插件提供并通过 NuGet 程序包管理。这样做的一个好处就是你可以升级应用的一个模块,但丝毫不会影响其他模块;另外,.NET Core 是一个跨平台的运行时,因此你可以在 OSX 或 Linux 操作系统上部署你的应用;它也是一个云优化的运行时,用于在云上部署和调试应用;NET Core 可以和你的应用程序一起被部署,当服务器上有多个.NET Core 版本时,你依旧可以运行 ASP.NET Core 应用。你也可以创建只运行在 windows 下完整.NET 框架的 ASP.NET Core 应用。ASP.NET 4.6 是最新的完整.NET Framework 的发布版本,它允许你可以利用所有的.NET 组件并且具备向后兼容能力。如果你计划将应用迁移到.NET core,那么你需要做适量的修改,因为.NET Core 相对于完整.NET Framework 来说有所限制。需要明确的是,ASP.NET 4.6 更加成熟。它如今久经考验并且现已发布并可使用。ASP.NET Core 1.0 是1.0 发布版本,包含 Web API 和 MVC,但是现在还没有 SignalR 和 Web Pages。它也不支持VB 和 F# 语言。ASP.NET Core 不再只依赖Visual StudioASP.NET Core 的跨平台,让它不再只依赖 Visual Studio,开发者和设计师们可以在自己喜欢的环境上工作。比如 Sublime Text,WebStorm,这真是太棒了!www.zgxue.com防采集请勿采集本网。

问题#

在开发微信支付的小微商户进件接口时,需要通过表单来上传身份证图片等数据。在微信支付接口文档也说明了,需要使用 multipart/form-data 的方式发送请求。.NET 提供了 MultipartFormDataContent 类型,帮助我们构建表单请求,故有以下代码:

但现在,它是Windows生态系统从物联网到云最宽泛的一部分。开发人员有更多选择,这在Microsoft的Visual Studio 在Windows Server Nano上运行.Net Core,使用熟悉的工具在Windows容器中构建和运行微服务。

var form = new MultipartFormDataContent(){ {new StringContent("Value"),"Name}, {new ByteArrayContent(new byte[]{}/*模拟文件数据*/),"File,"FileName}}

但现在,它是Windows生态系统从物联网到云最宽泛的一部分。开发人员有更多选择,这在Microsoft的Visual Studio 在Windows Server Nano上运行.Net Core,使用熟悉的工具在Windows容器中构建和运行微服务。

按照微信支付官方文档提交之后,一直提示参数错误,百思不得其解。

.NET Core默认使用了ids4,而且基于.NET Core构建的网站大多数都是使用的这个 注册和登陆的前端页面都在这里,这里使用了Razor语法,后台的登陆认证功能都集成在identityserver4里面了 startup

原因#

通过 Postman 模拟表单提交,捕获数据包,将其与 C# 的提交代码进行对比,发现了两处问题。

你可以理解为有这个版本。这要看用的底层框架,1.0就是说用的.NETFrameWork1.0类库1.1就是说用的.NETFrameWork1.1类库2.0就是说用的.NETFrameWork2.0类库区别并不大,详情请查看MSDN。

Postman 的原始提交:

在.NET Core和.NET Framework中都有效。其他值得一提的方法: 所有SymmetricAlgorithm实例都是IDisposable,您应该使用使用语句。所有ICryptoTransform实例未正确命名为 desEncryptor)为IDisposable,则

POST http://api.mch.weixin.qq.com/secapi/mch/uploadmedia HTTP/1.1

User-Agent: PostmanRuntime/7.21.0

Accept: */*

Cache-Control: no-cache

Postman-Token: b6800c0f-3f16-4981-b661-e6d16fc1bb1e

Host: api.mch.weixin.qq.com

Content-Type: multipart/form-data; boundary=--------------------------639275760242036520206377

Accept-Encoding: gzip, deflate

Content-Length: 566

Connection: keep-alive

----------------------------639275760242036520206377

Content-Disposition: form-data; name="mch_id"

1565111111

----------------------------639275760242036520206377

Content-Disposition: form-data; name="media_hash"

7215E92A8F3F3D0256484EFFF53A25F6

----------------------------639275760242036520206377

Content-Disposition: form-data; name="sign_type"

HMAC-SHA256

----------------------------639275760242036520206377

Content-Disposition: form-data; name="sign"

A1D8B094FA24BE5531D1AC198DE25550

----------------------------639275760242036520206377--

C# 代码的提交:

POST http://api.mch.weixin.qq.com/secapi/mch/uploadmedia HTTP/1.1

Host: api.mch.weixin.qq.com

Content-Type: multipart/form-data; boundary="e9d5712f-7923-4ec5-8bf3-c8d5d3cd3217"

Content-Length: 502

--e9d5712f-7923-4ec5-8bf3-c8d5d3cd3217

Content-Type: text/plain; charset=utf-8

Content-Disposition: form-data; name=mch_id

--e9d5712f-7923-4ec5-8bf3-c8d5d3cd3217

Content-Type: text/plain; charset=utf-8

Content-Disposition: form-data; name=media_hash

33F15BC2D17D6FFBC18FA566EF65722E

--e9d5712f-7923-4ec5-8bf3-c8d5d3cd3217

Content-Type: text/plain; charset=utf-8

Content-Disposition: form-data; name=sign

1E377684F9BD583D2ED26FB367916C0C

--e9d5712f-7923-4ec5-8bf3-c8d5d3cd3217--

1. Boundary 的双引号

使用 MultipartFormDataContent 提交的表单请求,外部 Content-Type 的 boundary 值带有 " 号。而 Postman 提交的表单请求,它的 boudary 值是没有双引号的。

那为什么会造成这样的差异呢?参考 这篇 博客的讲解,是由于各个系统/语言针对 RFC 2046 的实现不一致导致的。针对于 MultipartFormDataContent 的行为,如果 Boundary 后面的值带有双引号是符合标准的。

RFC 2612 原文:

2) Although RFC 2046 [40] permits the boundary string to be

quoted, some existing implementations handle a quoted boundary

string incorrectly.

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"}};

NET Core 使用Dapper 操作MySQL 数据库,.NET Core 使用Dapper。目前官方没有出.NET Core MySQL 驱动,但是已经有第三方进行改动封装出.NET Core MySQL Connector 预览版。Dapper 也已经出了.NET Core 预览版。Dapper dot net 是一个轻量型的ORM,但是性能很强大。有了.NET Core MySQL Connector 我们可以直接使用ADO.NET 操作数据库。目前EF Core 暂时不支持MySQL,本篇主要讲解使用Dapper 操作 MySQL。第三方 MySQL Connector:Dapper:新建项目新建一个.NET Core控制台应用程序 NETCoreMySQL内容来自www.zgxue.com请勿采集。


  • 本文相关:
  • httpclient模拟post请求json封装表单数据的实现方法
  • java利用httpclient模拟post表单操作应用及注意事项
  • asp.net 脏字典过滤问题 用正则表达式来过滤脏数据
  • asp.net基于ajax的enter键提交问题分析
  • c#各种集合操作的性能总结
  • asp.net mvc3关于生成纯静态后如何不再走路由直接访问静态页面
  • asp.net gridview与checkbox全选、全不选实现代码
  • 在c#及.net框架中使用stringbuilder类操作字符串的技巧
  • 解决uploadify使用时session发生丢失问题的方法
  • asp.net(c#)下各种进制间的轻松转换(2进制、8进制、10进制、16进
  • asp.net中读取xml文件信息的4种方法与示例代码
  • asp.net 购物车实现详细代码
  • net core 怎么操作数据库
  • net core 是最新的.net版本吗
  • net core 怎么操作数据库
  • 用什么可以开发net core
  • Net 框架和.Net Core,我该用哪个?怎么选
  • Net 框架和.Net Core,我该用哪个?怎么选
  • .net core 生成的身份认证的代码在哪?还有生成的注册和登录页面在哪?
  • net framework 可以使用 net core的类库吗
  • 如何使用Rijndael加密与.Net Core类库
  • 请问如何使用vscode打开.Net core项目?
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全基础应用实用技巧自学过程首页asp.net实用技巧java利用httpclient模拟post表单操作应用及注意事项asp.net 脏字典过滤问题 用正则表达式来过滤脏数据asp.net基于ajax的enter键提交问题分析c#各种集合操作的性能总结asp.net mvc3关于生成纯静态后如何不再走路由直接访问静态页面asp.net gridview与checkbox全选、全不选实现代码在c#及.net框架中使用stringbuilder类操作字符串的技巧解决uploadify使用时session发生丢失问题的方法asp.net(c#)下各种进制间的轻松转换(2进制、8进制、10进制、16进asp.net中读取xml文件信息的4种方法与示例代码asp.net 购物车实现详细代码java正则表达式 pattern和matche未将对象引用设置到对象的实例 (asp.net(c#)网页跳转七种方法小结未能加载文件或程序集“xxx”或它asp.net“服务器应用程序不可用”asp.net中的几种弹出框提示基本实asp.net gridview 72般绝技asp.net生成excel并导出下载五种asp.net汉字转拼音和获取汉字首字asp.net对路径"xxxxx"详解mvc中为dropdownlistfor设置选中项的高仿windows phone qq登录界面实例代码c# 连接字符串数据库服务器端口号 .net状gridview中动态设置commandfield是否可用asp.net控件10个最有用的属性详解.net从优酷专辑中采集所有视频及信息(vbasp.net截屏功能实现截取web页面asp.net中绑定textbox回车事件的解决方法aspx如果引用cs中的变量的方法asp.net中网站访问量统计方法代码
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved