WebAPI通过multipart/form-data方式同时上传文件以及数据(含HttpClient上传Demo)
简单的Demo,用于了解WebAPI如何同时接收文件及数据,同时提供HttpClient模拟如何同时上传文件和数据的Demo,下面是HttpClient上传的Demo界面
1、HttpClient部分:
HttpClient通过PostAsync提交数据时,第二个请求参数为抽象类HttpContent,当前我们需要通过multipart/form-data的方式模拟请求,multipart对应的请求HttpContent为MultipartContent及其子类MultipartFormDataContent,按名字明显可以看出MultipartFormDataContent对应multipart/form-data,MultipartFormDataContent可以通过Add方法添加具体的HttpContent,这里当然是添加ByteArrayContent了
下面是分别获取文件及键值对集合对应ByteArrayContent集合的代码
- /// <summary>
- /// 获取文件集合对应的ByteArrayContent集合
- /// </summary>
- /// <param name="files"></param>
- /// <returns></returns>
- private List<ByteArrayContent> GetFileByteArrayContent(HashSet<string> files)
- {
- List<ByteArrayContent> list = new List<ByteArrayContent>();
- foreach (var file in files)
- {
- var fileContent = new ByteArrayContent(File.ReadAllBytes(file));
- fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
- {
- FileName = Path.GetFileName(file)
- };
- list.Add(fileContent);
- }
- return list;
- }
- /// <summary>
- /// 获取键值集合对应的ByteArrayContent集合
- /// </summary>
- /// <param name="collection"></param>
- /// <returns></returns>
- private List<ByteArrayContent> GetFormDataByteArrayContent(NameValueCollection collection)
- {
- List<ByteArrayContent> list = new List<ByteArrayContent>();
- foreach (var key in collection.AllKeys)
- {
- var dataContent = new ByteArrayContent(Encoding.UTF8.GetBytes(collection[key]));
- dataContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
- {
- Name = key
- };
- list.Add(dataContent);
- }
- return list;
- }
然后提交Api部分的代码如下(如需完整代码,请至底部点击源代码下载链接)
- using (HttpClient client = new HttpClient())
- {
- client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/" + this.cmbResponseContentType.Text.ToLower()));//设定要响应的数据格式
- using (var content = new MultipartFormDataContent())//表明是通过multipart/form-data的方式上传数据
- {
- var formDatas = this.GetFormDataByteArrayContent(this.GetNameValueCollection(this.gv_FormData));//获取键值集合对应的ByteArrayContent集合
- var files = this.GetFileByteArrayContent(this.GetHashSet(this.gv_File));//获取文件集合对应的ByteArrayContent集合
- Action<List<ByteArrayContent>> act = (dataContents) =>
- {//声明一个委托,该委托的作用就是将ByteArrayContent集合加入到MultipartFormDataContent中
- foreach (var byteArrayContent in dataContents)
- {
- content.Add(byteArrayContent);
- }
- };
- act(formDatas);//执行act
- act(files);//执行act
- try
- {
- var result = client.PostAsync(this.txtUrl.Text, content).Result;//post请求
- this.txtResponse.Text = result.Content.ReadAsStringAsync().Result;//将响应结果显示在文本框内
- }
- catch (Exception ex)
- {
- this.txtResponse.Text = ex.ToString();//将异常信息显示在文本框内
- }
- }
- }
2、WebAPI部分
其实WebAPI这部分真的没什么,完全是参考了国外大牛的代码,不过某些不明了的地方在方法内有备注,有时间会去研究下如何才能实现无需保存文件至硬盘,即可获取相应的数据流
- [HttpPost]
- public async Task<Dictionary<string, string>> Post(int id = 0)
- {
- if (!Request.Content.IsMimeMultipartContent())
- {
- throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
- }
- Dictionary<string, string> dic = new Dictionary<string, string>();
- string root = HttpContext.Current.Server.MapPath("~/App_Data");//指定要将文件存入的服务器物理位置
- var provider = new MultipartFormDataStreamProvider(root);
- try
- {
- // Read the form data.
- await Request.Content.ReadAsMultipartAsync(provider);
- // This illustrates how to get the file names.
- foreach (MultipartFileData file in provider.FileData)
- {//接收文件
- Trace.WriteLine(file.Headers.ContentDisposition.FileName);//获取上传文件实际的文件名
- Trace.WriteLine("Server file path: " + file.LocalFileName);//获取上传文件在服务上默认的文件名
- }//TODO:这样做直接就将文件存到了指定目录下,暂时不知道如何实现只接收文件数据流但并不保存至服务器的目录下,由开发自行指定如何存储,比如通过服务存到图片服务器
- foreach (var key in provider.FormData.AllKeys)
- {//接收FormData
- dic.Add(key, provider.FormData[key]);
- }
- }
- catch
- {
- throw;
- }
- return dic;
- }
源代码下载,运行Demo时请先调试服务端,然后开启客户端,如果缺少HttpClient对应的dll,请通过NuGet下载
WebAPI通过multipart/form-data方式同时上传文件以及数据(含HttpClient上传Demo)的更多相关文章
- 一般处理程序上传文件(html表单上传、aspx页面上传)
html 表单上传文件 一般处理程序由于没有 apsx 页面的整个模型和控件的创建周期,而比较有效率.这里写一个用 html 表单进行文件上传的示例. 1. 表单元素选用 ...
- form上传文件以及跨域异步上传
要设置了enctype属性才能上传,需要使用上传的jar包,这里使用的是cos-26Dec2008.jar, 而且后台获取值的时候,getfile要放在第一位 一次设置好上传格式后没有上传文件,也就没 ...
- 使用WebClient Post方式模拟上传文件和数据
假如某网站有个表单,例如(url: http://localhost/login.aspx):帐号 密码 我们需要在程序中提交数据到这个表单,对于这种表单,我们可以使用 WebClient.Uplo ...
- c# 模拟表单提交,post form 上传文件、数据内容
转自:https://www.cnblogs.com/DoNetCShap/p/10696277.html 表单提交协议规定:要先将 HTTP 要求的 Content-Type 设为 multipar ...
- jQuery Ajax方式上传文件实现暂停或取消上传
未上传时要实现取消,很简单... 但如果用户点击了上传,并加载了进度信息... 2017-05-04再次改进.在上传过程中用户可以按 Esc 来取消上传(取消当前上传,或者是全部上传)... 也可以在 ...
- ajax异步上传文件和表单同步上传文件 的区别
1. 用表单上传文件(以照片为例)-同步上传 html部分代码:这里请求地址index.php <!DOCTYPE html> <html lang="en"&g ...
- Layui上传文件以及数据表格
layui对于一些前端小白来说,例如我,真的非常的好用,不用去花很多很多的心思在前端美化中,并且提高了很大的工作效率.所以建议一些觉得自己前端技术不是很强,但是想让前端美化一点的可以使用layui. ...
- plupload如何限制上传文件数量,限制只能上传单个文件
1 完整代码 $(function() { $("#uploader").pluploadQueue({ runtimes : 'html5,gears,flash,silverl ...
- 用java 代码下载Samba服务器上的文件到本地目录以及上传本地文件到Samba服务器
引入: 在我们昨天架设好了Samba服务器上并且创建了一个 Samba 账户后,我们就迫不及待的想用JAVA去操作Samba服务器了,我们找到了一个框架叫 jcifs,可以高效的完成我们工作. 实践: ...
随机推荐
- 定义自己的布局RelativeLayout
绘制网格线
在Android画线必须由一个载体,无论是控制,无论是布局.实际上它们是从继承View.由画线的方式自己的控制或布局的定义是最常见的. 以下是在其定义中的小样本实现RelativeLayout绘制网络 ...
- hdu3062(two-sat)
传送门:Party 题意:有n对夫妻被邀请参加一个聚会,因为场地的问题,每对夫妻中只有1人可以列席.在2n 个人中,某些人之间有着很大的矛盾(当然夫妻之间是没有矛盾的),有矛盾的2个人是不会同时出现在 ...
- (1)cocos2d-x-2.2.4搭建windows开发环境
Cocos2d-x-2.2.4搭建windows环境 软件需求 Windows系统(windows7或之后的系统): cocos2d-x-2.2.4压缩包. python安装包(推荐使用2.7.3版本 ...
- setChecked方法触发onCheckedChanged监听器问题
有时须要在程序初始化界面时,讲有些比如toggleButton等控件依照需求勾选,此时会发现,当我setChecked时会触发onCheckedChanged监听器,导致这部分代码被调用两次.解决方法 ...
- Web Api 2(Cors)Ajax跨域访问
支持Ajax跨域访问ASP.NET Web Api 2(Cors)的简单示例教程演示 随着深入使用ASP.NET Web Api,我们可能会在项目中考虑将前端的业务分得更细.比如前端项目使用Ang ...
- POJ 1703:Find them, Catch them(并用正确的设置检查)
Find them, Catch them Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 30702 Accepted: ...
- linux yum命令
1 安装yum install 全部安装yum install package1 安装指定的安装包package1yum groupinsall group1 安装程序组group1 2 更新和升级y ...
- 单点更新线段树 RMQ
D. Xenia and Bit Operations time limit per test 2 seconds memory limit per test 256 megabytes input ...
- 《JavaScript设计模式与开发实践》读书笔记之策略模式
1.策略模式 定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换 1.1 传统实现 根据工资基数和年底绩效来发送年终奖 var calculateBonus= function (perfo ...
- as 的妙用
个人理解:as跟is is 相当于判断里的“==” 是与否 if(e.OriginalSource is Button) as 一般用来转换另一种object e.OriginalSource as ...