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

以及蓝色框内的用分隔符分割的请求体中的内容。

在某些应用场景下,表单数据以键值对集合存储,然后将键值对集合上传到远程服务器。

通用方法如下:

 /// <summary>
/// HTTP请求(包含表单数据)
/// </summary>
/// <param name="url">请求目标URL</param>
/// <param name="kvDatas">请求时表单键值对数据</param>
/// <param name="method">请求的方法。请使用 WebRequestMethods.Http 的枚举值</param>
/// <returns></returns>
public HttpResult UploadForm(string url, NameValueCollection kvDatas, string method = WebRequestMethods.Http.Post)
{
HttpResult httpResult = new HttpResult();
HttpWebRequest httpWebRequest = null; try
{
httpWebRequest = WebRequest.Create(url) as HttpWebRequest;
httpWebRequest.Method = method;
httpWebRequest.Headers = HeaderCollection;
httpWebRequest.CookieContainer = CookieContainer;
httpWebRequest.ContentType = HttpContentType.WWW_FORM_URLENCODED;
httpWebRequest.UserAgent = _userAgent;
httpWebRequest.AllowAutoRedirect = _allowAutoRedirect;
httpWebRequest.ServicePoint.Expect100Continue = false; if (kvDatas != null)
{
StringBuilder sbKV = new StringBuilder();
foreach (string key in kvDatas.Keys)
{
sbKV.AppendFormat("{0}={1}&", Uri.EscapeDataString(key), Uri.EscapeDataString(kvDatas[key])); //注意中文编码
} httpWebRequest.AllowWriteStreamBuffering = true;
using (Stream requestStream = httpWebRequest.GetRequestStream())
{
requestStream.Write(EncodingType.GetBytes(sbKV.ToString()), , sbKV.Length - );
requestStream.Flush();
}
} HttpWebResponse httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse;
if (httpWebResponse != null)
{
GetResponse(ref httpResult, httpWebResponse);
httpWebResponse.Close();
}
}
catch (WebException webException)
{
GetWebExceptionResponse(ref httpResult, webException);
}
catch (Exception ex)
{
GetExceptionResponse(ref httpResult, ex, method, HttpContentType.WWW_FORM_URLENCODED);
}
finally
{
if (httpWebRequest != null)
{
httpWebRequest.Abort();
}
} return httpResult;
}

1、向 NameValueCollection 类中添加项时,键可以重复。

2、如果添加了C#中的某些关键字作为集合的键则会报错,解决方法是,给关键字添加前缀或者后缀,在解析时再去除前缀或者后缀。

借助于上述方法,又衍生出一个重载方法:

 /// <summary>
/// HTTP请求(包含表单数据)
/// </summary>
/// <param name="url">请求目标URL</param>
/// <param name="kvDatas">请求时表单键值对数据</param>
/// <param name="method">请求的方法。请使用 WebRequestMethods.Http 的枚举值</param>
/// <returns></returns>
public HttpResult UploadForm(string url, Dictionary<string, string> kvDatas, string method = WebRequestMethods.Http.Post)
{
var nvc = kvDatas.ToNameValueCollection(); return UploadForm(url, nvc, method);
}

Dictionary 字典中不能添加重复的键。

Dictionary 转换成 NameValueCollection 集合的扩展方法如下:
 /// <summary>
/// 自定义扩展方法:将字典转换为 NameValueCollection 集合对象
/// </summary>
/// <param name="dict">扩展对象</param>
/// <returns></returns>
public static NameValueCollection ToNameValueCollection<TKey, TValue>(this IDictionary<TKey, TValue> dict)
{
if (dict == null)
{
return null;
} var nameValueCollection = new NameValueCollection(); foreach (var item in dict)
{
string value = null;
if (item.Value != null)
{
value = item.Value.ToString();
} nameValueCollection.Add(item.Key.ToString(), value);
} return nameValueCollection;
}

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

C# HTTP系列12 以form-data方式上传键值对集合到远程服务器的更多相关文章

  1. C# HTTP系列13 以form-data方式上传多个文件以及键值对集合到远程服务器

    系列目录     [已更新最新开发文章,点击查看详细] 类似于以下场景,将表单中的用户信息(包含附件)上传到服务器并保存到数据库中, <form id="form1" run ...

  2. SpringMVC经典系列-12基于SpringMVC的文件上传---【LinusZhu】

    注意:此文章是个人原创.希望有转载须要的朋友们标明文章出处,假设各位朋友们认为写的还好,就给个赞哈,你的鼓舞是我创作的最大动力.LinusZhu在此表示十分感谢,当然文章中如有纰漏.请联系linusz ...

  3. python 处理form/data文件上传

    处理multipart/form-data 的java serverlet请求接口通过python实现 记住不要在头加:"Content-Type":"multipart ...

  4. 前端 - jquery方式 / iframe +form 方式 上传文件

    环境与上一章一样 jquery 方式上传文件: HTML代码 {#html代码开始#} <input type="file" id="img" > ...

  5. egg.js 通过 form 和 ajax 两种方式上传文件并自定义目录和文件名

    egg.js 通过 form 和 ajax 两种方式上传文件并自定义目录和文件名 评论:10 · 阅读:8437· 喜欢:0 一.需求 二.CSRF 校验 三.通过 form 表单上传文件 四.通过 ...

  6. 通过Ajax方式上传文件,使用FormData进行Ajax请求

    通过传统的form表单提交的方式上传文件: <form id= "uploadForm" action= "http://localhost:8080/cfJAX_ ...

  7. koa2:通过Ajax方式上传文件,使用FormData进行Ajax请求

    koa2通过表单上传的网上很多,但通过Ajax方式上传文件,使用FormData进行Ajax请求,不好找. 参考了这个用base64上传图片的例子.https://github.com/Yuki-Mi ...

  8. [转] 通过Ajax方式上传文件,使用FormData进行Ajax请求

    通过传统的form表单提交的方式上传文件: <form id= "uploadForm" action= "http://localhost:8080/cfJAX_ ...

  9. day059-60 ajax初识 登录认证练习 form装饰器, form和ajax上传文件 contentType

    一.ajax 的特点 1.异步交互:客户端发出一个请求后,需要等待服务器响应结束后, 才能发出第二个请求 2.局部刷新:给用户的感受是在不知不觉中完成请求和响应过程. 二.ajax 模板示例 ($.a ...

随机推荐

  1. System.InvalidOperationException: 'Cannot create more than one System.Windows.Application instance in the same AppDomain.'

    System.Windows.Application is a singleton: its constructor must only be invoked once (including App. ...

  2. Effective Python 编写高质量Python代码的59个有效方法

    Effective Python 编写高质量Python代码的59个有效方法

  3. SSM登陆

    简单的SSM登陆 jsp <form action="${pageContext.request.contextPath }/user/login.action"> & ...

  4. Python脚本1

    [轮子]P123. 求最大约数,并鉴别是否为素数

  5. Eureka源码解析系列文章汇总

    先看一张图 0 这个图是Eureka官方提供的架构图,整张图基本上把整个Eureka的核心功能给列出来了,当你要阅读Eureka的源码时可以参考着这个图和下方这些文章 EurekaServer Eur ...

  6. unity常用的坐标系转换

    当调用别人的接口时,经常会有获取位置或向量的接口.遇到这些数据时,先要弄清楚现在获取的数据在哪个坐标系下的. 是否需要进行坐标系变换,一般提供的位置和向量都是在世界坐标系的,此时需要注意: ①对方的坐 ...

  7. ptrace函数深入分析

    ptrace函数:进程跟踪. 形式:#include<sys/ptrace.h> Int ptrace(int request,int pid,int addr,int data); 概述 ...

  8. Visual Studio Code 远程开发探秘

    摘要: IDE新时代! 作者:SHUHARI 的博客 原文:Visual Studio Code 远程开发探秘 Fundebug按照原文要求转载,版权归原作者所有. 在以前的文章 有趣的项目 - 在浏 ...

  9. jar 冲突、class 冲突的检测脚本

    思路很简单,解开war包,解开 jar 包,发现有同名 package.class 就报出来,不管是否“兼容” .. import zipfile import io from collections ...

  10. Flask配置Cors跨域

    1 跨域的理解 跨域是指:浏览器A从服务器B获取的静态资源,包括Html.Css.Js,然后在Js中通过Ajax访问C服务器的静态资源或请求.即:浏览器A从B服务器拿的资源,资源中想访问服务器C的资源 ...