简单的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. Wamp环境下配置--Apache虚拟主机

    1.首先打开apache的配置文件httpd.conf,并去掉#Include conf/extra/httpd-vhosts.conf前面的#,启用虚拟主机功能 # Virtual hosts In ...

  2. Keil - 编译错误总结 01

    Keil 编译 STM32project,出现下述错误. 并且.   Options for Target  -> Output   -  Browse  Information 选项无法勾选. ...

  3. WCF之添加自定义用户名密码认证

    1.创建WCF服务应用以及调用客户端(请自行google).  2.创建X509证书       cmd 进入  C:\Program Files\Microsoft SDKs\Windows\v6. ...

  4. cocos2dx手写js绑定C++

    这两天连续查阅了js绑定c++的非常多文章  , 有手动与自己主动两种方式 . 本来想用自己主动绑定的 , 可是NDK一直下载不下来.....就给算了 . 以下总结一下手动绑定的实现过程 : 一共三步 ...

  5. 升级旧Delphi应用转向支持手机的一个思路

    系统架构改为B/S. 业务规则所有在服务端实现,使用REST服务封装旧有系统,这样可最大程度的利用原有代码. client所实用HTML5+javascript,这样client不须布署PC,可极大减 ...

  6. hadoop在实现kmeans算法——一个mapreduce实施

    写mapreduce程序实现kmeans算法.我们的想法可能是 1. 次迭代后的质心 2. map里.计算每一个质心与样本之间的距离,得到与样本距离最短的质心,以这个质心作为key,样本作为value ...

  7. 4句代码读取Excel到DataSet(非Excel组件)

    Toxy是继NPOI之后主推的还有一个项目,主要目的是为了解决文档的抽取问题.其支持的格式包括全部docx.xlsx.xls.csv.vcard等. 以下是一个简单但非常实用的样例 ParserCon ...

  8. Conversion to Dalvik format failed: Unable to execute dex

    最近莫名奇妙遇到“Conversion to Dalvik format failed: Unable to execute dex”错误,stackoverflow以后得到结果 把项目中classp ...

  9. The Building Blocks-Enterprise Applications Part 2- Information Management and Business Analytics

    1. Business Analytic Applications Data Analytics Also referred to as 'Business Analytics' or 'Busine ...

  10. 【leetcode】Candy(python)

    题目要求的比它的邻居比自己奖励,因此,我们有最少一个多的.所有我们可以找到所有的坑,凹坑例如,存在以下三种情况. 找到全部的凹点后,我们就能够从凹点处開始向左右两个方向依次查找递增序列.当中每一个高的 ...