关于 MemoryStream 的多次写入,模拟post请求,接收方 .net core web api无法读取到流数据,报 System.IO.IOException: Unexpected end of Stream, the content may have already be en read by another component.
主要是业务不熟害死人。记录一下。真想抽自己几个嘴巴子
先说结论,知道这个结论的下面文字都是废话:
一、new MemoryStream 的时候,如果需要分次写入,只能是像下面这样子
MemoryStream ms =new MemoryStream()
ms.write(第一次的byte[])
ms.write(第二次的byte[])
而不能像下面这样子。
MemoryStream ms =new MemoryStream(第一次的byte[])
ms.writer(第二次的byte[])
如果像下面这样子,ms的大小是固定的,写入的时候会把之前写入的覆盖
二、如果是把ms赋值给其他字段,需要把 ms 的Position设置为0,即 ms.Position=0,否则别人可能读不到数据。
再说一下自己艰辛的调试过程
在捣鼓ocelot网关中心,转发一个请求去别人的服务器,这个请求是 Content-Type: multipart/form-data;
既有参数,又有文件。
但是我网关收到参数后,需要对参数进行一定的鉴权,再转发参数去别人的下游服务。
所以我就把参数全部取出来后做处理了,处理完了以后,需要把它弄成一个Stream流 放在Body中。这个是一个.net core 的中间件

当我很开心的处理完了以后,以为没什么问题,postman搞起,结果并没有得到自己想要的结果,似乎对方的服务器没收到参数。
我的body体大概就是像下面这个,(先忽略文件,不好表述,用文本的好表述)
----------------------------585497138534118524577705
Content-Disposition: form-data; name="userId"
123
----------------------------585497138534118524577705
Content-Disposition: form-data; name="username"
1111111
----------------------------585497138534118524577705--
然后我发现,假设我先把这整段body体拼好设定变量 string bodyStr=上面那段body,然后 MemoryStream ms=new MemoryStream (Encoding.GetEncoding(charset).GetBytes(bodyStr);
然后 httpContext.Request.Body = ms; 这样子请求,对方正常接到参数。
假设我分次 ms.write() ,对方怎么都收不到参数。
我分词伪代码大概就是
MemoryStream ms =new MemoryStream(第一次的byte[])
ms.writer(第二次的byte[])
我又不能问对方(对方是淘宝。。。没空帮我查这种自己写代码造成的问题)
然后我就把 ms 又转回字符串去观察,发现第一次写入的bytep[]的字符串总会少一些,果断去查资料。
原来实例化 MemoryStream 的时候,如果传入了 byte[] ,那这个内存块就是固定大小的,所以会一直覆盖吧。
所以我代码换成了
MemoryStream ms =new MemoryStream()
ms.write(第一次的byte[])
ms.write(第二次的byte[])
心里想着这次应该对了。结果对方似乎还是收不到我的参数。我特么。。。。
我继续把ms的字符串打印出来观察,发现的的确确已经对了,类似下面这个
----------------------------585497138534118524577705
Content-Disposition: form-data; name="userId"
123
----------------------------585497138534118524577705
Content-Disposition: form-data; name="username"
1111111
----------------------------585497138534118524577705--
所以,我写给对方的body体肯定对了,对方也不可能出错,毕竟对方是淘宝。
这里面肯定还有问题。没办法,既然找不到他们答复,那我就只能把请求转发给我自己的下游先试试了
我马上拿web api 搭建了一个 printPara()的方法。主要代码是 打印当前请求的所有参数以及请求头键值对。
结果发现,.net core 给我报了一个错 ,如下图

所以,没跑了,对方肯定也是这样子了。
然后,百度各种搜这个错误,好像没什么有价值的资料。
但是我估摸着,它既然提示说这个流可能被其他人读过了,那答案应该就只有一个,大概就是指针位置到末尾了。所以我就尝试在第二次 ms.write 后把 ms.Position=0 给加上。
再发请求,就可以了。。。
唉。主要还是业务部署害死自己。整整调了一个下午加晚饭后的休息时间。唉
主要还是因为极少用这个MemoryStream和基本功不扎实吧。
关于 MemoryStream 的多次写入,模拟post请求,接收方 .net core web api无法读取到流数据,报 System.IO.IOException: Unexpected end of Stream, the content may have already be en read by another component.的更多相关文章
- HttpClient模拟客户端请求实例
HttpClient Get请求: /// <summary> /// Get请求模拟 /// </summary> /// < ...
- python入门常用方法(转json,模拟浏览器请求头,写入文件)
转json import jsonjson = json.loads(html) 模拟浏览器请求头 import urllib.request req = urllib.request.Request ...
- 用python的Requests库模拟http请求
一.先了解几个重要的http请求头或响应头信息 Request Headers: Host: 描述请求将被发送的目的地,包括,且仅仅包括域名和端口号. Origin: 说明请求从哪里发起的,包括,且仅 ...
- python模拟http请求2
发现了一个非常好用的第三方module:requests,模拟接口非常简单. 详细了解请移步:http://docs.python-requests.org/en/latest/ 非常不错 #!cod ...
- python模拟Get请求保存网易歌曲的url
python模拟Get请求保存网易歌曲的url 作者:vpoet mail:vpoet_sir@163.com 日期:大约在夏季 #coding:utf-8 import requests impor ...
- 使用 HttpWebRequest 发送模拟 POST 请求
使用HttpWebRequest发送模拟POST请求 网页中,如果form的method="POST",这时点击submit按钮可以给服务器发送了一个POST请求,如果metho ...
- php curl模拟post请求提交数据样例总结
在php中要模拟post请求数据提交我们会使用到curl函数,以下我来给大家举几个curl模拟post请求提交数据样例有须要的朋友可參考參考.注意:curl函数在php中默认是不被支持的,假设须要使用 ...
- 第五十九节,模拟浏览器请求Python结合html基本格式
模拟浏览器请求Python结合html基本格式 用Python模拟一个客户端,结合打开一个HTML页面 创建客户端 #!/usr/bin/env python # -*- coding:utf8 -* ...
- socket 模拟 HTTP请求
一.socket介绍 网络由下往上分为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层.IP协议对应于网络层,TCP协议对应于传输层,而HTTP协议对应于应用层.socket则是对TCP/I ...
- php模拟http请求
在http简析中,我们提到了浏览器请求资源的一个流程,那么这个流程能不能用php来模拟呢?答案是肯定的. php模拟http请求需要实现以下步骤: 1.连接apache服务器 使用fsockopen: ...
随机推荐
- Oracle 锁表查询和解锁方法
system登录 查询被锁表信息 select sess.sid, sess.serial#, lo.oracle_username, lo.os_user_name, ao.object_name, ...
- WebGL实践之半透阴影
楔子 相信很多人都知道,通过ShadowMap可以产生阴影,通过渲染阴影可以增加场景渲染的对比度,增加渲染的真实效果. 如下图所示: 但是对于透明或者半透明的对象,WebGL在处理阴影效果的时候,会把 ...
- [oeasy]python0070_动态类型_静态类型_编译_运行_匈牙利命名法
动态类型_静态类型 回忆上次内容 上次了解了 帮助文档的 生成 开头的三引号注释 可以生成 帮助文档 文档 可以写成网页 python3 本身 也有 在线的帮助手册 目前的程序 提高了 可 ...
- Vue 结合html2canvas和jsPDF实现html页面转pdf
结合html2canvas和jsPDF实现html页面转pdf By:授客 QQ:103355122 实践环境 win10 Vue 2.9.6 axios 0.18.0 html2ca ...
- ffmpeg精简
自:http://www.chinavideo.org/viewthread.php?tid=5567&extra=page%3D1&page=2 现在更新一下目前遇到的问题: 我想裁 ...
- Django+Bootstrip 卡片模板设计 经典精品
下面是一个完整的卡片模板代码,包含所有元素,并使用Django的模板语言来处理状态字段的条件渲染.同时还包括示例视图和URL配置. 完整的卡片模板 <div class="card&q ...
- 为什么我@Value中明明显示了值,他却是null
今天尝试把一些重要东西写入application.yml里,结果在使用的时候发现value取不出来值原因有2个: 1.没有写@compent,没有把这个类交给spring管理 2.在service层n ...
- 【Java】Vue-Element-Admin 嵌入Druid监控面板
我看到若依做了Druid面板的嵌入,我自己的项目干脆也做一个 一.后台服务SpringBoot: Druid配置项: spring: datasource: url: jdbc:mysql://127 ...
- 【Keepalived】KP + NGINX 多机热备学习
案例搭建 环境是三台机器,两台也可以 最后一个IP是测试的VIP 192.168.124.21 centos6-1 192.168.124.22 centos6-2 192.168.124.23 ce ...
- 【Java】 WebService 校验机制
测试环境域名 不可见 正式环境域名 不可见 1.2.安全校验凭证 accessId(授权ID) 测试/正式待定 securityKey(加密密钥) 测试/正式待定 1.3.安全校验机制 1.3.1.在 ...