简单的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集合的代码

  1. /// <summary>
  2. /// 获取文件集合对应的ByteArrayContent集合
  3. /// </summary>
  4. /// <param name="files"></param>
  5. /// <returns></returns>
  6. private List<ByteArrayContent> GetFileByteArrayContent(HashSet<string> files)
  7. {
  8. List<ByteArrayContent> list = new List<ByteArrayContent>();
  9. foreach (var file in files)
  10. {
  11. var fileContent = new ByteArrayContent(File.ReadAllBytes(file));
  12. fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
  13. {
  14. FileName = Path.GetFileName(file)
  15. };
  16. list.Add(fileContent);
  17. }
  18. return list;
  19. }
  20. /// <summary>
  21. /// 获取键值集合对应的ByteArrayContent集合
  22. /// </summary>
  23. /// <param name="collection"></param>
  24. /// <returns></returns>
  25. private List<ByteArrayContent> GetFormDataByteArrayContent(NameValueCollection collection)
  26. {
  27. List<ByteArrayContent> list = new List<ByteArrayContent>();
  28. foreach (var key in collection.AllKeys)
  29. {
  30. var dataContent = new ByteArrayContent(Encoding.UTF8.GetBytes(collection[key]));
  31. dataContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
  32. {
  33. Name = key
  34. };
  35. list.Add(dataContent);
  36. }
  37. return list;
  38. }

然后提交Api部分的代码如下(如需完整代码,请至底部点击源代码下载链接)

  1. using (HttpClient client = new HttpClient())
  2. {
  3. client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/" + this.cmbResponseContentType.Text.ToLower()));//设定要响应的数据格式
  4. using (var content = new MultipartFormDataContent())//表明是通过multipart/form-data的方式上传数据
  5. {
  6. var formDatas = this.GetFormDataByteArrayContent(this.GetNameValueCollection(this.gv_FormData));//获取键值集合对应的ByteArrayContent集合
  7. var files = this.GetFileByteArrayContent(this.GetHashSet(this.gv_File));//获取文件集合对应的ByteArrayContent集合
  8. Action<List<ByteArrayContent>> act = (dataContents) =>
  9. {//声明一个委托,该委托的作用就是将ByteArrayContent集合加入到MultipartFormDataContent中
  10. foreach (var byteArrayContent in dataContents)
  11. {
  12. content.Add(byteArrayContent);
  13. }
  14. };
  15. act(formDatas);//执行act
  16. act(files);//执行act
  17. try
  18. {
  19. var result = client.PostAsync(this.txtUrl.Text, content).Result;//post请求
  20. this.txtResponse.Text = result.Content.ReadAsStringAsync().Result;//将响应结果显示在文本框内
  21. }
  22. catch (Exception ex)
  23. {
  24. this.txtResponse.Text = ex.ToString();//将异常信息显示在文本框内
  25. }
  26. }
  27. }

2、WebAPI部分

其实WebAPI这部分真的没什么,完全是参考了国外大牛的代码,不过某些不明了的地方在方法内有备注,有时间会去研究下如何才能实现无需保存文件至硬盘,即可获取相应的数据流

  1. [HttpPost]
  2. public async Task<Dictionary<string, string>> Post(int id = 0)
  3. {
  4. if (!Request.Content.IsMimeMultipartContent())
  5. {
  6. throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
  7. }
  8. Dictionary<string, string> dic = new Dictionary<string, string>();
  9. string root = HttpContext.Current.Server.MapPath("~/App_Data");//指定要将文件存入的服务器物理位置
  10. var provider = new MultipartFormDataStreamProvider(root);
  11. try
  12. {
  13. // Read the form data.
  14. await Request.Content.ReadAsMultipartAsync(provider);
  15. // This illustrates how to get the file names.
  16. foreach (MultipartFileData file in provider.FileData)
  17. {//接收文件
  18. Trace.WriteLine(file.Headers.ContentDisposition.FileName);//获取上传文件实际的文件名
  19. Trace.WriteLine("Server file path: " + file.LocalFileName);//获取上传文件在服务上默认的文件名
  20. }//TODO:这样做直接就将文件存到了指定目录下,暂时不知道如何实现只接收文件数据流但并不保存至服务器的目录下,由开发自行指定如何存储,比如通过服务存到图片服务器
  21. foreach (var key in provider.FormData.AllKeys)
  22. {//接收FormData
  23. dic.Add(key, provider.FormData[key]);
  24. }
  25. }
  26. catch
  27. {
  28. throw;
  29. }
  30. return dic;
  31. }

源代码下载,运行Demo时请先调试服务端,然后开启客户端,如果缺少HttpClient对应的dll,请通过NuGet下载

WebAPI通过multipart/form-data方式同时上传文件以及数据(含HttpClient上传Demo)的更多相关文章

  1. 一般处理程序上传文件(html表单上传、aspx页面上传)

    html 表单上传文件        一般处理程序由于没有 apsx 页面的整个模型和控件的创建周期,而比较有效率.这里写一个用 html 表单进行文件上传的示例.        1. 表单元素选用 ...

  2. form上传文件以及跨域异步上传

    要设置了enctype属性才能上传,需要使用上传的jar包,这里使用的是cos-26Dec2008.jar, 而且后台获取值的时候,getfile要放在第一位 一次设置好上传格式后没有上传文件,也就没 ...

  3. 使用WebClient Post方式模拟上传文件和数据

    假如某网站有个表单,例如(url: http://localhost/login.aspx):帐号  密码 我们需要在程序中提交数据到这个表单,对于这种表单,我们可以使用 WebClient.Uplo ...

  4. c# 模拟表单提交,post form 上传文件、数据内容

    转自:https://www.cnblogs.com/DoNetCShap/p/10696277.html 表单提交协议规定:要先将 HTTP 要求的 Content-Type 设为 multipar ...

  5. jQuery Ajax方式上传文件实现暂停或取消上传

    未上传时要实现取消,很简单... 但如果用户点击了上传,并加载了进度信息... 2017-05-04再次改进.在上传过程中用户可以按 Esc 来取消上传(取消当前上传,或者是全部上传)... 也可以在 ...

  6. ajax异步上传文件和表单同步上传文件 的区别

    1. 用表单上传文件(以照片为例)-同步上传 html部分代码:这里请求地址index.php <!DOCTYPE html> <html lang="en"&g ...

  7. Layui上传文件以及数据表格

    layui对于一些前端小白来说,例如我,真的非常的好用,不用去花很多很多的心思在前端美化中,并且提高了很大的工作效率.所以建议一些觉得自己前端技术不是很强,但是想让前端美化一点的可以使用layui. ...

  8. plupload如何限制上传文件数量,限制只能上传单个文件

    1 完整代码 $(function() { $("#uploader").pluploadQueue({ runtimes : 'html5,gears,flash,silverl ...

  9. 用java 代码下载Samba服务器上的文件到本地目录以及上传本地文件到Samba服务器

    引入: 在我们昨天架设好了Samba服务器上并且创建了一个 Samba 账户后,我们就迫不及待的想用JAVA去操作Samba服务器了,我们找到了一个框架叫 jcifs,可以高效的完成我们工作. 实践: ...

随机推荐

  1. jquery.ui.accordion的修改(支持展开多个)

    原文:jquery.ui.accordion的修改(支持展开多个) 背景:原jquery.ui.accordion插件,最多只能展开一个,不能展开多个,后来在网上找到了一个基于它的一个修改版(http ...

  2. 标准输入的原理:cin与scanf

    1.cin 该方法 1)假设cin读取整数.会自己主动忽略换行和空格.遇到文件结束标记.cin  >> a返回的数false     int a;     while(cin >&g ...

  3. Python-方法重载的问题

    定义一个父类,在写一个子类继承他,重载他的foo方法: class Father: def foo(self): print"I am father" class Son(Fath ...

  4. HDU 3304 Interesting Yang Yui Triangle lucas定理

    输入p n 求杨辉三角的第n+1行不能被p整除的数有多少个 Lucas定理: A.B是非负整数,p是质数.AB写成p进制:A=a[n]a[n-1]...a[0],B=b[n]b[n-1]...b[0] ...

  5. c语言推断数是否是素数

    这是推断数是否是素数.网络版非常.我觉得有点问题.今天一个朋友问我这个问题.我知道,今天,我把自己的代码,非常实用哦!. #include<stdio.h> #include<mat ...

  6. POJ3050 Hopscotch 【DFS】

    Hopscotch Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2113   Accepted: 1514 Descrip ...

  7. Learning Cocos2d-x for WP8(2)——深入刨析Hello World

    原文:Learning Cocos2d-x for WP8(2)--深入刨析Hello World cocos2d-x框架 在兄弟篇Learning Cocos2d-x for XNA(1)——小窥c ...

  8. HttpClient 4.3教程(转载)

    HttpClient 4.3教程(转载) 转自:http://www.yeetrack.com/?p=779 前言 Http协议应该是互联网中最重要的协议.持续增长的web服务.可联网的家用电器等都在 ...

  9. 站点接入QQ登录

    首先引入授权js文件 <script type="text/javascript" src="http://qzonestyle.gtimg.cn/qzone/op ...

  10. duilib底层机制剖析:窗口类与窗口句柄的关联

    转载请说明原出处.谢谢~~ 看到群里朋友有人讨论WTL中的thunk技术,让我联想到了duilib的类似技术. 这些技术都是为了解决c++封装的窗口类与窗口句柄的关联问题. 这里是三篇关于thunk技 ...