博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WebAPI通过multipart/form-data方式同时上传文件以及数据(含HttpClient上传Demo)
阅读量:5281 次
发布时间:2019-06-14

本文共 3722 字,大约阅读时间需要 12 分钟。

简单的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] 
 
  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] 
 
  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] 
 
  1. [HttpPost]  
  2. public async Task<Dictionary<string, string>> Post(int id = 0)  
  3. {  
  4.   
  5.     if (!Request.Content.IsMimeMultipartContent())  
  6.     {  
  7.         throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);  
  8.     }  
  9.     Dictionary<string, string> dic = new Dictionary<string, string>();  
  10.     string root = HttpContext.Current.Server.MapPath("~/App_Data");//指定要将文件存入的服务器物理位置  
  11.     var provider = new MultipartFormDataStreamProvider(root);  
  12.     try  
  13.     {  
  14.         // Read the form data.  
  15.         await Request.Content.ReadAsMultipartAsync(provider);  
  16.   
  17.         // This illustrates how to get the file names.  
  18.         foreach (MultipartFileData file in provider.FileData)  
  19.         {
    //接收文件  
  20.             Trace.WriteLine(file.Headers.ContentDisposition.FileName);//获取上传文件实际的文件名  
  21.             Trace.WriteLine("Server file path: " + file.LocalFileName);//获取上传文件在服务上默认的文件名  
  22.         }//TODO:这样做直接就将文件存到了指定目录下,暂时不知道如何实现只接收文件数据流但并不保存至服务器的目录下,由开发自行指定如何存储,比如通过服务存到图片服务器  
  23.         foreach (var key in provider.FormData.AllKeys)  
  24.         {
    //接收FormData  
  25.             dic.Add(key, provider.FormData[key]);  
  26.         }  
  27.     }  
  28.     catch  
  29.     {  
  30.         throw;  
  31.     }  
  32.     return dic;  
  33. }  

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

转载于:https://www.cnblogs.com/simadi/p/5032320.html

你可能感兴趣的文章
Yum安装MySQL以及相关目录路径和修改目录
查看>>
java获取hostIp和hostName
查看>>
关于web服务器和数据库的各种说法(搜集到的)
查看>>
C# Stream 和 byte[] 之间的转换
查看>>
OMG: daily scrum nine
查看>>
redis与spring结合错误情况
查看>>
第六章 字节码执行方式--解释执行和JIT
查看>>
字符串方法title()、istitle()
查看>>
yield语句
查看>>
查看linux系统中占用cpu最高的语句
查看>>
[洛谷P1738]洛谷的文件夹
查看>>
ubuntu server设置时区和更新时间
查看>>
【京东咚咚架构演进】-- 好文收藏
查看>>
【HTML】网页中如何让DIV在网页滚动到特定位置时出现
查看>>
文件序列化
查看>>
jQuery之end()和pushStack()
查看>>
Bootstrap--响应式导航条布局
查看>>
Learning Python 009 dict(字典)和 set
查看>>
JavaScript中随着鼠标拖拽而移动的块
查看>>
HDU 1021 一道水题
查看>>