平時使用各種網絡傳輸的時候基本上是以Json格式進行的, 所以對其他幾種格式也是一知半解, 今天靜下心對其好好梳理一番.
首先我借鑒了一篇文章(https://segmentfault.com/a/1190000014343759), 和大多數資料一樣, 他將類型分為四大類
application/x-www-form-urlencoded, multipart/form-data, application/json, text/xml.
我把他的介紹Copy了過來, 這幾種確實挺常用的, 但是個人而言, 我用的最多的還是json, 而xml我幾乎只在配置文件有直接接觸.
做一個可能不專業的總結, 有錯誤請指正:
Json的使用主要是由於REST的興起, 而且當下流行前后端分離, 后端使用輕量級的webapi, 幾乎和json捆綁到一塊了.
Xml的傳輸場景則是基於SOAP(Simple Object Access Protocol), 這個好像接觸到的都是Java開發的.
一、以下是最常用的四種類型:
(1)、application/x-www-form-urlencoded
這應該是最常見的 POST 提交數據的方式了。瀏覽器的原生 <form> 表單,如果不設置 enctype 屬性,那么最終就會以 application/x-www-form-urlencoded 方式提交數據。
<form action="form_action.asp" enctype="text/plain"> <p>First name: <input type="text" name="fname" /></p> <p>Last name: <input type="text" name="lname" /></p> <input type="submit" value="Submit" /> </form>
(2)、multipart/form-data
這也是常見的post請求方式,一般用來上傳文件,各大服務器的支持也比較好。所以我們使用表單 上傳文件 時,必須讓<form>表單的enctype屬性值為 multipart/form-data.
(3)、application/json
application/json作為響應頭並不陌生,實際上,現在很多時候也把它作為請求頭,用來告訴服務端消息主體是序列化的JSON字符串,除了低版本的IE,基本都支持。除了低版本的IE都支持JSON.stringify()的方法,服務端也有處理JSON的函數,使用json不會有任何麻煩。
(4)、text/xml
二、個人對傳輸類型進行的分類
其實這個介紹我認為一點都不具備概括性, 開發的同學肯定都使用過一個叫做Postman的東西

Get請求都是通過URL進行傳參的, 也就是我們途中看到的Params, 而Post請求除了可以通過Params來傳參, 最關鍵的則是Body, URL攜帶的參數基本限定在字符串, 並且需要進行URL轉碼, 而Body里面則可以有各種格式.
當然none則是沒有Body, 不作考慮, 拎出來兩個特別的:
1、form-data, 也就是上文中介紹的multipart/form-data, 他通過一個叫做boundary的東西來隔絕鍵值對, 下面是截圖:


2、binary, 這個看名字就能猜出一二, 這個是直接通過二進制流進行傳輸的, 這個也沒啥好解釋的.
剩下的, 我都歸類到其他類型, 他們有一個共同的特性, Body內容是一長串字符串, 而在Header里面會有一個Content-Type的屬性來告訴接收者這個字符串是怎么組織的.


但是這里面還有一個稍微特別一點的, 就是application/x-www-form-urlencoded, 他需要進行URL轉碼, 他和Get請求的URL轉碼是一個意思.
不同的是, Get請求直接拼接到URL上即可, 而該類型則是放到Body, 同時加一個Content-Type的Header.
三、C#中HttpClient進行各種類型的傳輸

我們可以看到, 盡管PostAsync有四個重載函數, 但是接受的都是HttpContent, 而查看源碼可以看到, HttpContent是一個抽象類

那我們就不可能直接創建HttpContent的實例, 而需要去找他的實現類, 經過一番研究, 發現了, 如下四個:
MultipartFormDataContent、FormUrlEncodedContent、StringContent、StreamContent
和上面的總結進行一個對比就能發現端倪:
MultipartFormDataContent=》multipart/form-data
FormUrlEncodedContent=》application/x-www-form-urlencoded
StringContent=》application/json等
StreamContent=》binary
而和上面總結的一樣FormUrlEncodedContent只是一個特殊的StringContent罷了, 唯一不同的就是在mediaType之前自己手動進行一下URL編碼罷了(這一條純屬猜測, 邏輯上應該是沒有問題的).
