使用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. gitLab 分支保护设置

    一.需求背景 开发当前开发的分支遇到暂时无法解决的问题,现在有需要开发其他应用,所以希望运维这边将当前有问题分支冻结,让其他人无法进行修改,待后续有时间在排查代码问题 二.Gitlab配置步骤 1.搜 ...

  2. 使用SolrJ(即java客户端)开发Solr。

    1.什么是SolrJ呢? 答:Solrj是访问Solr服务的java客户端,提供索引和搜索的请求方法,SolrJ通常在嵌入在业务系统中,通过SolrJ的API接口操作Solr服务.开始配置schema ...

  3. ElasticSearch简介(一)——基础

    基本概念 1.  Node 与 Cluster Elastic 本质上是一个分布式数据库,允许多台服务器协同工作,每台服务器可以运行多个 Elastic 实例. 单个 Elastic 实例称为一个节点 ...

  4. 【IPHONE开发-OBJECTC入门学习】复制对象,深浅复制

    转自:http://blog.csdn.net/java886o/article/details/9046273 #import <Foundation/Foundation.h> int ...

  5. RPC 初识

    RPC是什么 RPC(Remote Procedure Call) 释义是远程过程调用,常存在于分布式系统中. 比如说现在有两台服务器A, B,一个在A服务器上的应用想要调用B服务器上的应用提供的某个 ...

  6. tcpdump 介绍

    tcpdump 是一款强大的网络抓包工具,dump the traffice on anetwork,对网络上的数据包进行截获的包分析工具.熟练掌握 tcpdump 可以方便我们跟踪解决网络丢包,重传 ...

  7. cpu开多少线程合适(转)

    影响最佳线程数的主要因素: 1.IO 2.CPU 根据公式:服务器端最佳线程数量=((线程等待时间+线程cpu时间)/线程cpu时间) * cpu数量 一般来说是IO和CPU.IO开销较多的应用其CP ...

  8. Linux上安装nginx

    环境:centos7   nginx1.16.1(源码安装) 一.下载nginx源码包 地址:http://nginx.org/en/download.html Mainline version(主线 ...

  9. <人人都懂设计模式>-单例模式

    这个模式,我还是了解的. 书上用了三种不同的方法. class Singleton1: # 单例实现方式1 __instance = None __is_first_init = False def ...

  10. C语言的常量

    #include<stdio.h> int main(void) { ; //定义一个常量,不能被修改,可以赋初值:常量的标识符建议使用大写字母 ; //初始化 printf(" ...