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,可以高效的完成我们工作. 实践: ...
随机推荐
- POJ 2826 An Easy Problem?! 好的标题
受该两块木板以形成槽的效果.Q槽可容纳雨水多,注意雨爆跌,思想是非常easy,分类讨论是有点差. 1.假定两条线段不相交或平行,然后再装0: 2.有一个平行x轴.连衣裙0. 3.若上面覆盖以下的,装0 ...
- mini2440驱动奇谭——ADC驱动与測试(动态挂载驱动)
博客:http://blog.csdn.net/muyang_ren 实现功能:开发板动态载入adc驱动模块并能通过測试程序 系统:Ubuntu 14.04 驱动交叉编译内核:linux-2. ...
- jdk1.6与1.7垃圾回收
最近项目中遇到了个关于JVM中GC线程数的问题,做一下简单的总结 问题场景: server:均为 sun公司的solaris 系统 CPU 128个 项目8.1时使用的 java版本: jdk1. ...
- JVM学习03_new对象的内存图讲解,以及引出static方法(转)
目录 -=-讲解对象创建过程中,-=-堆内存和栈内存的情况 -=-构造函数对类对象的成员变量的初始化过程 -=-构造函数出栈 -=-类的方法在不访问类对象的成员变量时造成的内存资源浪费怎么解决? -= ...
- 在IIS上发布Web(使用VS2005)
最近想在IIS上发布网站,弄了一下午.遇到很多问题,幸运的是都一一解决了,现在把解决问题的过程分享出来: 安装好IIS后,在VS2005上写了个网站(新建-->网站-->ASP.NET网站 ...
- SWT中的Tree中 添加右键弹出菜单
先看一下效果: 如图:在树上单击鼠标右键会弹出 弹出式菜单.做法其实很简单,先做一个树: final TreeViewer treeViewer = new TreeViewer(group, SWT ...
- coding.net解决github上下载速度慢问题
由 于众所周知的原因,从github下载项目很慢,一般不超过10kb(我的是20兆公司网)例如我下载OpenRefine,没有3个小时搞不定.所以想 到了一个方法来解决他.就是使用国内其他代码托管平台 ...
- Android-IA Power Manager (S3)
Sleep and wake up
- hdu 2082 生成函数
主题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2082 找单词 Time Limit: 1000/1000 MS (Java/Others) Me ...
- 安装Python和pip
windows下面安装Python和pip终极教程 在大二的时候接触过一段时间的Python,最近又开始玩起了这门语言.总的来说,个人很喜欢Python的语言风格,但是这门语言对于windows并不算 ...