zoukankan      html  css  js  c++  java
  • C# HTTP系列12 以form-data方式上传键值对集合到远程服务器

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

    源码下载链接: https://pan.baidu.com/s/1bYh2COYxxeG1WIYJt6Wsnw 提取码: ysqd

  • 相关阅读:
    C++ 内置宏定义 与 预编译指令
    C++ 反射机制的简单实现
    Intellij打包jar文件,“java.lang.SecurityException: Invalid signature file digest for Manifest main attrib
    IntelliJ IDEA 运行你的第一个Java应用程序 idea运行main方法
    IDEA重新打jar包时报错MANIFEST.MF already exists in VFS
    在 RPA10.X 运行异常,RPA9 却正常的问题处理
    Python判断文件是否存在的三种方法
    Python日期时间函数
    Chrome提示:"请停用以开发者模式运行的扩展程序"的解决办法
    Win10提示“无法打开此计算机上的组策略对象”如何解决
  • 原文地址:https://www.cnblogs.com/SavionZhang/p/11419559.html
Copyright © 2011-2022 走看看