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

简介:

WebAPI通过multipart/form-data方式同时上传文件以及数据(含HttpClient上传Demo)http://www.bieryun.com/1086.html


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

[csharp] view plain copy

  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部分的代码如下(如需完整代码,请至底部点击源代码下载链接)

[csharp] view plain copy

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

[csharp] view plain copy

  1. [HttpPost]
  2. public async Task<Dictionary<stringstring>> Post(int id = 0)
  3. {
  4.     if (!Request.Content.IsMimeMultipartContent())
  5.     {
  6.         throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
  7.     }
  8.     Dictionary<stringstring> dic = new Dictionary<stringstring>();
  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. }

 

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

PS:补充由服务端指定文件存储位置博客地址

相关文章
|
移动开发 Java
java发送post请求,使用multipart/form-data的方式传递参数
java发送post请求,使用multipart/form-data的方式传递参数
991 0
|
11天前
|
JavaScript
vue element upload组件配合axios实现用 “Content-Type“: “multipart/form-data“上传方式导入xls文件
vue element upload组件配合axios实现用 “Content-Type“: “multipart/form-data“上传方式导入xls文件
|
4月前
|
Java
【Java报错】MultipartFile 类型文件上传 Current request is not a multipart request 问题处理(postman添加MultipartFile)
【Java报错】MultipartFile 类型文件上传 Current request is not a multipart request 问题处理(postman添加MultipartFile)
148 0
|
7月前
|
JavaScript
如何使用 multiparty 工具库在 Node.js 应用里解析 multipart form-data 格式的请求
如何使用 multiparty 工具库在 Node.js 应用里解析 multipart form-data 格式的请求
68 1
|
8月前
|
人工智能 Java 应用服务中间件
SpringBoot实战(十一):MultipartException: Could not parse multipart servlet request
SpringBoot实战(十一):MultipartException: Could not parse multipart servlet request
103 0
Springboot Http文件的访问 Url 转换 MultipartFile ,File 转 MultipartFile
Springboot Http文件的访问 Url 转换 MultipartFile ,File 转 MultipartFile
619 0
|
数据采集 Python
Python 文件上传:如何使用 multipart/form-data 编码和 requests 包
为 Python 标准库没有提供创建 multipart/form-data 编码类型请求的内置方法,这种编码类型允许发送二进制数据和其他表单字段。因此,在 Python 文件上传时,程序必须要么使用第三方库,要么手动构造请求体和头部。其中一个比较简单的方法是使用 requests 包(PyPI 链接),简单快捷的在 Python 3 中使用Requests 包,通过Multipart/Form-Data 编码并上传文件。
653 0
Python 文件上传:如何使用 multipart/form-data 编码和 requests 包
|
前端开发 JavaScript Java
【前端】form标签multipart/form-data 文件上传表单中 传递参数无法获取的原因
form标签multipart/form-data 文件上传表单中 传递参数无法获取的原因
724 1
C#使用HttpClient上传文件(multipart表单)
C#使用HttpClient上传文件(multipart表单)
2211 0
|
Python
Python Request POST 上传文件 Multipart/form-data
Python Request POST 上传文件 Multipart/form-data
666 0
Python Request POST 上传文件 Multipart/form-data