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

  • 2019 年 10 月 5 日
  • 筆記

系列目錄 【已更新最新開發文章,點擊查看詳細】

使用multipart/form-data方式提交數據與普通的post方式有一定區別。multipart/form-data的請求頭必須包含一個特殊的頭資訊:Content-Type,其值必須為multipart/form-data。另外還需要規定一個內容分割符用於分割請求體中的多個post的內容,如文件內容和文本內容,只有這樣服務端才能正常解析數據。但是,multipart/form-data的基礎還是post,它是由post方法來實現的。

點擊【Code】按鈕,打開如下窗體:

可以看到 Content-Type: multipart/form-data; boundary=—-WebKitFormBoundary7MA4YWxkTrZu0gW

以及藍色框內的用分隔符分割的請求體中的內容。

在某些應用場景下,表單數據以鍵值對集合存儲,然後將鍵值對集合上傳到遠程伺服器。

通用方法如下:

 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 }

1、向 NameValueCollection 類中添加項時,鍵可以重複。 2、如果添加了C#中的某些關鍵字作為集合的鍵則會報錯,解決方法是,給關鍵字添加前綴或者後綴,在解析時再去除前綴或者後綴。

藉助於上述方法,又衍生出一個重載方法:

 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 字典中不能添加重複的鍵。

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 }

系列目錄 【已更新最新開發文章,點擊查看詳細】