简单的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. poj2479(dp)

    题目链接:http://poj.org/problem?id=2479 题意:求所给数列中元素值和最大的两段子数列之和. 分析:从左往右扫一遍,b[i]表示前i个数的最大子数列之和. 从右往左扫一遍, ...

  2. hdu1876(dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1876 题意:问机器人到达终点的过程中最多有几次完全消耗完能量,消耗完这么多次能量的方式有几种. 分析: ...

  3. POJ 2756 Autumn is a Genius 大数加减法

    Description Jiajia and Wind have a very cute daughter called Autumn. She is so clever that she can d ...

  4. Maven, Ivy, Grape, Gradle, Buildr, SBT, Leiningen, ant

    Maven, Ivy, Grape, Gradle, Buildr, SBT, Leiningen, ant

  5. Cocos2d-x发展---更改父的颜色、透明度的子节点上

    标题手段:当我们改变父节点或透明时的颜色.默认是不会影响孩子的节点. 作为交换组看到朋友说可以通过设置相关的参数变化的子节点来实现属性的效果,看了看源代码,记录下来:        引擎版本号为:2. ...

  6. OCP读书笔记(19) - 数据库空间管理

    传输表空间:将linux下的数据库中的test表空间传输到windows平台下的数据库 在传输表空间前,先确定一下源库与目标数据库字符集一致: select * from nls_database_p ...

  7. Android 上实现非root的 Traceroute -- 非Root权限下移植可运行二进制文件 脚本文件

    作者 : 万境绝尘 转载请著名出处 : http://blog.csdn.net/shulianghan/article/details/36438365 演示样例代码下载 : -- CSDN : h ...

  8. hdu1500 (排序+单调队列优化 )

    从n根筷子里面, 选择k+8个集合的筷子,每个集合三根筷子, A<=B<=C, 费用是(A-B)^2, 问最小的费用是多少. 将n根筷子排序之后,可以知道A和B的下标一定是连续的. 比如有 ...

  9. Android Material Design-Creating Lists and Cards(创建列表和卡)-(三)

    转载请注明出处:http://blog.csdn.net/bbld_/article/details/40430319 翻译自:http://developer.android.com/trainin ...

  10. swift学习笔记(六)析关闭过程和使用分配给属性的默认值

    一.通过关闭和功能的默认实现财产值 当存储属性默认值需要定制,能为客户提供通过关闭或全局函数的自定义默认值. 注意:全局函数的结构,和枚举使用keywordstatic大喊    用classkeyw ...