主要是業務不熟害死人。記錄一下。真想抽自己幾個嘴巴子
先說結論,知道這個結論的下面文字都是廢話:
一、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和基本功不扎實吧。