简单的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. NET Core 1.0 RC2

    NET Core 1.0 RC2 历险之旅 文章背景:对于.NET Core大家应该并不陌生, 从它被 宣布 到现在已经有1-2年的时间了,其比较重要的一个版本1.0 RC2 也即将发布..Net C ...

  2. [置顶] ANDROID 返回,菜单和HOME键的监听

    ------网上找了很多资料,项目中使用,最后将经验总结如下: 1,返回和菜单键是可以直接重写onKeyDown(int keyCode, KeyEvent event) 方法监听: @Overrid ...

  3. poj2236(并查集)

    题目连接 题意:一张图上分布着n台坏了的电脑,并知道它们的坐标.两台修好的电脑如果距离<=d就可以联网,也可以通过其他修好的电脑间接相连.给出操作“O x”表示修好x,给出操作“S x y”,请 ...

  4. leetcode 之 Permutation Sequence

    Permutation Sequence The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and ...

  5. Ubuntu下将vim配置为Python IDE(转)

    工欲善其事,必先利其器. 配置好了Django的环境,该把vim好好配置一下当做python的IDE来用. 在Windows下用惯了各种现成的工具,转到Linux下,一下没了头绪……好歹google出 ...

  6. 图片预览插件 fancyBox

    今天给大家分享一款优秀的 jquery 弹出层展示插件 fancybox. 它除了能够展示图片之外,还能够展示 flash.iframe 内容.html 文本以及 ajax 调用.我们能够通过 css ...

  7. Thinkphp中field和getField

    在数据库查询操作中field和getField方法是使用最频繁的.可是两者是有一定差别的.在这里记录下. field方法是用于定义要查询的字段(支持字段排除). getField方法获取数据表中的某个 ...

  8. Macosx Setdns

    通过C语言接口在Mac App内部对系统的DNS配置进行改动. Mac OS X设置DNS代码 演示样例代码setDNS.c内容例如以下: #include <SystemConfigurati ...

  9. OCP读书笔记(17) - 计划任务

    轻量级作业: 也称为持久性轻量级作业,如果当我们的数据库每秒钟需要创建.删除或修改数十个或数百个作业时,使用轻量级作业是降低开销的最佳方法 常规作业:是由oracle 11g Scheduler 所支 ...

  10. Xamarin C# Android for Visual Studio 平台安装

    原文:Xamarin C# Android for Visual Studio 平台安装 Xamarin是基于Mono的平台,目前主要有以下产品(更具体请见:http://xamarin.com/pr ...