C#中后臺post請求常用的兩種方式總結
最近對接接口的時候,需要根據(jù)對方的請求數(shù)據(jù)類型來進行傳值,常用的就是application/x-www-form-urlencoded,ajax提交數(shù)據(jù)時也是使用的這種方式,但是沒辦法傳遞文件之類的信息,另一種就是mutipart/form-data,可以同時傳遞參數(shù)與文件或二進制流,這里主要使用的就是這兩種方式
1.application/x-www-form-urlencoded
首先創(chuàng)建一個HttpWebRequest,并且聲明請求方法和請求頭
程序使用HTTP協(xié)議和服務器交互主要是進行數(shù)據(jù)的提交,通常數(shù)據(jù)的提交是通過 GET 和 POST 兩種方式來完成,
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded;charset:utf-8";
然后,我們需要進行拼接參數(shù),這種請求方式,提交的數(shù)據(jù)按照 key1=val1&key2=val2 的方式進行編碼,key 和 val 都進行了 URL 轉碼。
大部分服務端語言都對這種方式有很好的支持,這里使用foreach進行循環(huán)拼接
StringBuilder paraStrBuilder = new StringBuilder(); foreach (string key in postParameters.Keys) { paraStrBuilder.AppendFormat("{0}={1}&", key, postParameters[key]); } string para = paraStrBuilder.ToString(); if (para.EndsWith("&")) para = para.Remove(para.Length - 1, 1);
接著,將參數(shù)轉為ASCII碼,并且將參數(shù)寫入請求中
byte[] bt = Encoding.UTF8.GetBytes(para); string responseData = String.Empty; request.ContentLength = bt.Length; //GetRequestStream 輸入流數(shù)據(jù) using (Stream reqStream = request.GetRequestStream()) { reqStream.Write(bt, 0, bt.Length); reqStream.Close(); }
后面就是發(fā)送請求,獲取響應內(nèi)容
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { Stream stream = response.GetResponseStream(); using (StreamReader streamReader = new StreamReader(stream, Encoding.UTF8)) { retString = streamReader.ReadToEnd().ToString(); } }
這樣,一個完整的post請求就完成了,還是比較簡單的
2.mutipart/form-data
這種方式就比較麻煩了,常用于表單提交文件數(shù)據(jù)并且包含參數(shù)的形式,我們可以先通過postman請求,看一下請求正文是什么內(nèi)容
這個是一個附件上傳的接口,包含了附件信息和一些參數(shù)信息,首先聲明了請求類型是mutipart/form-data,后面跟了一個boundary,并且內(nèi)容是隨機的,緊接著又以一段隨機字符串開始,聲明了第一個參數(shù)名name=“file”,然后換了兩行,跟了文件信息,又是以同樣的一段的字符串進行分割,拼接下一段參數(shù)信息,這個地方多試幾遍,并且看看他的結構就能很好的寫代碼了
我們這里演示兩種方式,方便大家理解,一種是參數(shù)里不含任何文件信息,只有keyvalue,另一種是包含了文件信息且還有額外參數(shù)
首先是第一種,沒有文件信息
還是先創(chuàng)建一個http并聲明請求頭
var webRequest = (HttpWebRequest)WebRequest.Create(strUrl); var boundary = "---------------" + DateTime.Now.Ticks.ToString("x"); // 邊界符 var beginBoundary = Encoding.ASCII.GetBytes("--" + boundary + "\r\n"); // 最后的結束符 var endBoundary = Encoding.ASCII.GetBytes("--" + boundary + "--\r\n"); memStream.Write(beginBoundary, 0, beginBoundary.Length); // 設置屬性 webRequest.Method = "POST"; webRequest.Timeout = 10000; webRequest.ContentType = "multipart/form-data; boundary=" + boundary;
第二行創(chuàng)建一個boundary作為分割字符,然后在聲明一個起始位置與結束位置,詳見postm請求圖中第5行和第30行,就是起始標識與結束標識,并創(chuàng)建一個MemoryStream,不斷的寫入
然后進行參數(shù)拼接,這里要注意上圖里,每個參數(shù)的格式
foreach (string key in postParameters.Keys) { var stringKeyHeader = "Content-Disposition: form-data; name=\"{0}\"" + "\r\n\r\n{1}\r\n"; var header = string.Format(stringKeyHeader, key, postParameters[key]); var headerbytes = Encoding.UTF8.GetBytes(header); memStream.Write(headerbytes, 0, headerbytes.Length); }
每一個Content-Disposition: form-data; name=""后,進行了兩次換行,才拼接了值,然后又進行了一次換行沒有文件信息就不拼接間隔值,繼續(xù)拼接下一個值,在所有的值拼接完成后,加上結束標識
memStream.Write(endBoundary, 0, endBoundary.Length);
然后將拼接完成的流,重新寫入請求流中
webRequest.ContentLength = memStream.Length; var requestStream = webRequest.GetRequestStream(); memStream.Position = 0; var tempBuffer = new byte[memStream.Length]; memStream.Read(tempBuffer, 0, tempBuffer.Length); memStream.Close(); requestStream.Write(tempBuffer, 0, tempBuffer.Length); requestStream.Close();
后面就是發(fā)送請求,拿回響應內(nèi)容
using (HttpWebResponse res = (HttpWebResponse)webRequest.GetResponse()) { using (Stream resStream = res.GetResponseStream()) { byte[] buffer = new byte[1024]; int read; while ((read = resStream.Read(buffer, 0, buffer.Length)) > 0) { responseContent += Encoding.UTF8.GetString(buffer, 0, read); } } res.Close(); } return responseContent;
到此,不包含文件信息的請求就完成了
第二種,包含了文件信息,且也包含參數(shù),本質上只是多了一步單獨的拼接步驟,所以這步可以放在所有的參數(shù)拼接完成后,緊接著繼續(xù)拼接文件信息參數(shù),所以這一步的代碼,應該放在foreach之后且在foreach里需要拼接間隔值,這里就只放這一塊的代碼了,注意,如果在foreach之后還要繼續(xù)拼接參數(shù),就不要加結束標識
const string filePartHeader = "Content-Disposition: form-data; name=\"file\"; filename=\"{0}\"\r\n" + "Content-Type: application/octet-stream\r\n\r\n"; var header1 = string.Format(filePartHeader, postParameters["realName"]); var headerbytes1 = Encoding.UTF8.GetBytes(header1); memStream.Write(headerbytes1, 0, headerbytes1.Length); memStream.Write(FileByte, 0, FileByte.Length); string end = "\r\n"; headerbytes1 = Encoding.UTF8.GetBytes(end); memStream.Write(headerbytes1, 0, headerbytes1.Length); memStream.Write(endBoundary, 0, endBoundary.Length);
先按照格式編寫參數(shù)名Content-Disposition: form-data; name=""; filename="" Content-Type: ,然后連續(xù)換兩行,寫入文件流,在換行寫入結束標識,后面步驟就一樣,只要看懂了開始的那張圖,剩下的都是按照格式去拼接寫入就好
到此帶文件信息的傳參也完成了,接觸的越多,能學習的就越多,會的越多,不會的就越多,還有其他的請求方式我這里就不在詳細介紹了!
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
C# Winform 實現(xiàn)控件自適應父容器大小的示例代碼
這篇文章主要介紹了C# Winform 實現(xiàn)控件自適應父容器大小的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-03-03C#使用偽隨機數(shù)實現(xiàn)加密用戶密碼的方法
這篇文章主要介紹了C#使用偽隨機數(shù)實現(xiàn)加密用戶密碼的方法,對于開發(fā)C#會員系統(tǒng)或者程序安全問題都有一定的參考借鑒價值,需要的朋友可以參考下2014-07-07c#將字節(jié)數(shù)組轉成易讀的字符串的實現(xiàn)
這篇文章主要介紹了c#將字節(jié)數(shù)組轉成易讀的字符串的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-01-01