使用multipart/form-data方式提交數據與普通的post方式有必定區別。multipart/form-data的請求頭必須包含一個特殊的頭信息:Content-Type,其值必須爲multipart/form-data。另外還須要規定一個內容分割符用於分割請求體中的多個post的內容,如文件內容和文本內容,只有這樣服務端才能正常解析數據。可是,multipart/form-data的基礎仍是post,它是由post方法來實現的。html
點擊【Code】按鈕,打開以下窗體:web
能夠看到 Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW服務器
以及藍色框內的用分隔符分割的請求體中的內容。post
在某些應用場景下,表單數據以鍵值對集合存儲,而後將鍵值對集合上傳到遠程服務器。ui
通用方法以下:this
1 /// <summary> 2 /// HTTP請求(包含表單數據) 3 /// </summary> 4 /// <param name="url">請求目標URL</param> 5 /// <param name="kvDatas">請求時表單鍵值對數據</param> 6 /// <param name="method">請求的方法。請使用 WebRequestMethods.Http 的枚舉值</param> 7 /// <returns></returns> 8 public HttpResult UploadForm(string url, NameValueCollection kvDatas, string method = WebRequestMethods.Http.Post) 9 { 10 HttpResult httpResult = new HttpResult(); 11 HttpWebRequest httpWebRequest = null; 12 13 try 14 { 15 httpWebRequest = WebRequest.Create(url) as HttpWebRequest; 16 httpWebRequest.Method = method; 17 httpWebRequest.Headers = HeaderCollection; 18 httpWebRequest.CookieContainer = CookieContainer; 19 httpWebRequest.ContentType = HttpContentType.WWW_FORM_URLENCODED; 20 httpWebRequest.UserAgent = _userAgent; 21 httpWebRequest.AllowAutoRedirect = _allowAutoRedirect; 22 httpWebRequest.ServicePoint.Expect100Continue = false; 23 24 if (kvDatas != null) 25 { 26 StringBuilder sbKV = new StringBuilder(); 27 foreach (string key in kvDatas.Keys) 28 { 29 sbKV.AppendFormat("{0}={1}&", Uri.EscapeDataString(key), Uri.EscapeDataString(kvDatas[key])); //注意中文編碼 30 } 31 32 httpWebRequest.AllowWriteStreamBuffering = true; 33 using (Stream requestStream = httpWebRequest.GetRequestStream()) 34 { 35 requestStream.Write(EncodingType.GetBytes(sbKV.ToString()), 0, sbKV.Length - 1); 36 requestStream.Flush(); 37 } 38 } 39 40 HttpWebResponse httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse; 41 if (httpWebResponse != null) 42 { 43 GetResponse(ref httpResult, httpWebResponse); 44 httpWebResponse.Close(); 45 } 46 } 47 catch (WebException webException) 48 { 49 GetWebExceptionResponse(ref httpResult, webException); 50 } 51 catch (Exception ex) 52 { 53 GetExceptionResponse(ref httpResult, ex, method, HttpContentType.WWW_FORM_URLENCODED); 54 } 55 finally 56 { 57 if (httpWebRequest != null) 58 { 59 httpWebRequest.Abort(); 60 } 61 } 62 63 return httpResult; 64 }
一、向 NameValueCollection 類中添加項時,鍵能夠重複。編碼
二、若是添加了C#中的某些關鍵字做爲集合的鍵則會報錯,解決方法是,給關鍵字添加前綴或者後綴,在解析時再去除前綴或者後綴。url
藉助於上述方法,又衍生出一個重載方法:spa
1 /// <summary> 2 /// HTTP請求(包含表單數據) 3 /// </summary> 4 /// <param name="url">請求目標URL</param> 5 /// <param name="kvDatas">請求時表單鍵值對數據</param> 6 /// <param name="method">請求的方法。請使用 WebRequestMethods.Http 的枚舉值</param> 7 /// <returns></returns> 8 public HttpResult UploadForm(string url, Dictionary<string, string> kvDatas, string method = WebRequestMethods.Http.Post) 9 { 10 var nvc = kvDatas.ToNameValueCollection(); 11 12 return UploadForm(url, nvc, method); 13 }
Dictionary 字典中不能添加劇復的鍵。3d
Dictionary 轉換成 NameValueCollection 集合的擴展方法以下:
1 /// <summary> 2 /// 自定義擴展方法:將字典轉換爲 NameValueCollection 集合對象 3 /// </summary> 4 /// <param name="dict">擴展對象</param> 5 /// <returns></returns> 6 public static NameValueCollection ToNameValueCollection<TKey, TValue>(this IDictionary<TKey, TValue> dict) 7 { 8 if (dict == null) 9 { 10 return null; 11 } 12 13 var nameValueCollection = new NameValueCollection(); 14 15 foreach (var item in dict) 16 { 17 string value = null; 18 if (item.Value != null) 19 { 20 value = item.Value.ToString(); 21 } 22 23 nameValueCollection.Add(item.Key.ToString(), value); 24 } 25 26 return nameValueCollection; 27 }