简单的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. 【POJ 1741】Tree

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 11570   Accepted: 3626 Description ...

  2. CC ANUMLA(STL的运用)

    题目连接:http://www.codechef.com/problems/ANUMLA 题意:给一个序列所有子集和(2^n个子集),复原这个序列... 如:0 1 1 2 2 3 3 4 原序列为1 ...

  3. Oracle 最简单的随系统自己主动启动

    Oracle 最简单的随系统自己主动启动 俗话说用户是上帝,他们有时候提出一个问题很的简单,就仅仅须要一句话,一分钟就完事了.可是拿到我们DBA来说,可能至少得半个小时甚至半个月才干满足他的一句话.有 ...

  4. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第15章节--开发SP2013工作流应用程序 总结

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第15章节--开发SP2013工作流应用程序 总结         在SP2013中,工作流已经从SP Server中脱离 ...

  5. CSS背景图拉伸自适应尺寸

    .bg{ background:url(images/test.jpg); filter:"progid:DXImageTransform.Microsoft.AlphaImageLoade ...

  6. HDU1071 The area 【积分】

    The area Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  7. Wooden Sticks(杭州电1051)

    Wooden Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

  8. Python学习入门基础教程(learning Python)--3.2 if-else分支语句

    if-else分支语句结构的特点是当conditon条件满足时,执行if下的语句块,当condition条件不满足时执行else下的语句块,也就是说根据条件来控制让某些语句执行,某些语句不被执行. i ...

  9. 分解XML方法

    分解XML方法 1.DOM生成和解析XML 2.SAX生成和解析XML 3.DOM4J生成和解析XML 4.JDOM生成和解析XML 版权声明:本文博主原创文章.博客,未经同意不得转载.

  10. DataTable筛选器

    //datatable筛选器,函数包装模板:传入源table,目标table,db名,多表查询table,列条件数组,where筛选列,selsect筛选列 public DataTable Filt ...