C# HTTP系列12 以form-data方式上傳鍵值對集合到遠程服務器

使用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 }

 

相關文章
相關標籤/搜索