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,可以高效的完成我们工作. 实践: ...
随机推荐
- weblogic环境,应用上传图片报Could not initialize class sun.awt.X11.XToolkit
问题描写叙述 遇到的问题是在weblogic环境,应用在上传图片的时候报Could not initialize class sun.awt.X11.XToolkit 错误. 详细错误例如以下 17: ...
- tomcat 下部署 php
由于需要测试一个PHP的环境.故记录此处. 环境 OS:win8.1 up1 64bit tomcat :8.0.14 64bit php:php-5.6.2-Win32-VC11-x64.zip 将 ...
- TypeError: Cannot read property 'style' of null 错误解决
错误信息例如以下: JSP代码例如以下: <c:if test ="${not empty excelErrors}"> <div id="excelE ...
- MBR格式无法识别2T以上的硬盘的问题
早上有人打电话说四块2T的sata 硬盘做了raid 5之后安装window server 2012的时候,无法创建分区,安装完系统后无法给剩余的硬盘创建分区,刚开始的时候我还以为是别人分区的数量问题 ...
- Smarty模板引擎的使用
Smarty模板引擎的使用 Smarty是PHP中一个基于MVC模式的模板引擎. Download: http://www.smarty.net/download 特点 1. 最快速度的程序开发 ...
- SVN基于Maven的Web项目更新,本地过程详细解释
周围环境 MyEclipse:10.7 Maven:3.1.1 概要 最近在做项目,MyEclipse下载SVN基于上述Maven的Web问题,有时候搞了非常半天,Maven项目还是出现叉号,最后总结 ...
- SRM 219 Div II Level One: WaiterTipping,小心约分
题目来源:http://community.topcoder.com/stat?c=problem_statement&pm=12609&rd=15503 这题目看上去so easy, ...
- JAVA 读取图片储存至本地
需求:serlvet经过处理通过报表工具返回一张报表图(柱状图 折线图). 现在需要把这个图存储到本地 以便随时查看 // 构造URL URL url = new URL(endStr); // 打开 ...
- WPF界面设计技巧(5)—自定义列表项呈现内容
原文:WPF界面设计技巧(5)-自定义列表项呈现内容 接续上次的程序,稍微改动一下原有样式,并添加一个数据模板,我们就可以达成下面这样的显示功能: 鼠标悬停于文件列表项上,会在工具提示中显示图像缩略图 ...
- C++基础学习教程(八)
转载请注明出处:http://blog.csdn.net/suool/article/details/38300117 引入 在进行下一步的学习之前,我们须要厘清几个概念. RAII 首先介绍一个编程 ...