主要是业务不熟害死人。记录一下。真想抽自己几个嘴巴子

先说结论,知道这个结论的下面文字都是废话:

一、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.的更多相关文章

  1. HttpClient模拟客户端请求实例

    HttpClient Get请求: /// <summary>        /// Get请求模拟        /// </summary>        /// < ...

  2. python入门常用方法(转json,模拟浏览器请求头,写入文件)

    转json import jsonjson = json.loads(html) 模拟浏览器请求头 import urllib.request req = urllib.request.Request ...

  3. 用python的Requests库模拟http请求

    一.先了解几个重要的http请求头或响应头信息 Request Headers: Host: 描述请求将被发送的目的地,包括,且仅仅包括域名和端口号. Origin: 说明请求从哪里发起的,包括,且仅 ...

  4. python模拟http请求2

    发现了一个非常好用的第三方module:requests,模拟接口非常简单. 详细了解请移步:http://docs.python-requests.org/en/latest/ 非常不错 #!cod ...

  5. python模拟Get请求保存网易歌曲的url

    python模拟Get请求保存网易歌曲的url 作者:vpoet mail:vpoet_sir@163.com 日期:大约在夏季 #coding:utf-8 import requests impor ...

  6. 使用 HttpWebRequest 发送模拟 POST 请求

    使用HttpWebRequest发送模拟POST请求  网页中,如果form的method="POST",这时点击submit按钮可以给服务器发送了一个POST请求,如果metho ...

  7. php curl模拟post请求提交数据样例总结

    在php中要模拟post请求数据提交我们会使用到curl函数,以下我来给大家举几个curl模拟post请求提交数据样例有须要的朋友可參考參考.注意:curl函数在php中默认是不被支持的,假设须要使用 ...

  8. 第五十九节,模拟浏览器请求Python结合html基本格式

    模拟浏览器请求Python结合html基本格式 用Python模拟一个客户端,结合打开一个HTML页面 创建客户端 #!/usr/bin/env python # -*- coding:utf8 -* ...

  9. socket 模拟 HTTP请求

    一.socket介绍 网络由下往上分为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层.IP协议对应于网络层,TCP协议对应于传输层,而HTTP协议对应于应用层.socket则是对TCP/I ...

  10. php模拟http请求

    在http简析中,我们提到了浏览器请求资源的一个流程,那么这个流程能不能用php来模拟呢?答案是肯定的. php模拟http请求需要实现以下步骤: 1.连接apache服务器 使用fsockopen: ...

随机推荐

  1. 基于 tc 指令的网速限制工具

    前言 最近有一个需求,需要限制网卡速度进行一些测试.在朋友推荐下阅读了这篇文章 TC简单粗暴限制网速. 经过尝试,简单有效,整理成脚本放在正文,留作参考. 正文 指令解析(chatgpt 分析) 您提 ...

  2. 谈谈你对 keep-alive 的了解?

    在做电商有关的项目中,当我们第一次进入列表页需要请求一下数据,当我从列表页进入详情页,详情页不缓存也需要请求下数据,然后返回列表页,这时候我们使用keep-alive来缓存组件,防止二次渲染,这样会大 ...

  3. position的值, relative和absolute分别是相对于谁进行定位的?

    relative:  相对定位,相对于自己本身在正常文档流中的位置进行定位 相对它原来的位置,在走100px.原来在标准流中的位置继续占有. absolute: 生成绝对定位,相对于最近一级定位不为s ...

  4. 使用浏览器的cookies进行登陆

    1.使用浏览器Cookie登陆 In [ ]: cookie = 'uniqueVisitorId=a2151df1-4833-00ae-72e0-f4b99d2b7be2; pgv_pvid=232 ...

  5. 12 二次打开pdf失败

    h5 安卓 iOS均出现pdf二次打开失败

  6. Django 自带忘记密码,密码重置功能

    registration/password_reset_form.html: 重置密码表单模板 registration/password_reset_email.html: 发送重置密码邮件模板 r ...

  7. [oeasy]python0068_控制序列_清屏_控制输出位置_2J

    光标位置 回忆上次内容 上次了解了键盘演化的过程 ESC 从 组合键 到 独立按键 ESC 的目的 是进入控制序列 配置控制信息 控制信息 \033[y;xH 设置光标位置 \033[2J 清屏 这到 ...

  8. 深入探究 Golang 反射:功能与原理及应用

    Hi 亲爱的朋友们,我是 k 哥.今天,咱们来一同探讨下 Golang 反射. Go 出于通用性的考量,提供了反射这一功能.借助反射功能,我们可以实现通用性更强的函数,传入任意的参数,在函数内通过反射 ...

  9. C# 开发技巧 轻松监控方法执行耗时

    前言 MethodTimer.Fody 是一个功能强大的库,可以用于测量 .NET 应用程序中的方法的执行时间.允许你在不修改代码的情况下,自动地测量和记录方法的执行时间. 这个工具是基于.NET的 ...

  10. linux一行执行多条命令 shell

    要实现在一行执行多条Linux命令,分三种情况: 1.&& 举例: lpr /tmp/t2 && rm /tmp/t2 第2条命令只有在第1条命令成功执行之后才执行.当 ...