WebAPI通过multipart/form-data方式同时上传文件以及数据(含HttpClient上传Demo)
2015-04-30 13:01
881 查看
简单的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集合的代码
2、WebAPI部分
其实WebAPI这部分真的没什么,完全是参考了国外大牛的代码,不过某些不明了的地方在方法内有备注,有时间会去研究下如何才能实现无需保存文件至硬盘,即可获取相应的数据流
源代码下载,运行Demo时请先调试服务端,然后开启客户端,如果缺少HttpClient对应的dll,请通过NuGet下载
1、HttpClient部分:
HttpClient通过PostAsync提交数据时,第二个请求参数为抽象类HttpContent,当前我们需要通过multipart/form-data的方式模拟请求,multipart对应的请求HttpContent为MultipartContent及其子类MultipartFormDataContent,按名字明显可以看出MultipartFormDataContent对应multipart/form-data,MultipartFormDataContent可以通过Add方法添加具体的HttpContent,这里当然是添加ByteArrayContent了
下面是分别获取文件及键值对集合对应ByteArrayContent集合的代码
/// <summary> /// 获取文件集合对应的ByteArrayContent集合 /// </summary> /// <param name="files"></param> /// <returns></returns> private List<ByteArrayContent> GetFileByteArrayContent(HashSet<string> files) { List<ByteArrayContent> list = new List<ByteArrayContent>(); foreach (var file in files) { var fileContent = new ByteArrayContent(File.ReadAllBytes(file)); fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = Path.GetFileName(file) }; list.Add(fileContent); } return list; } /// <summary> /// 获取键值集合对应的ByteArrayContent集合 /// </summary> /// <param name="collection"></param> /// <returns></returns> private List<ByteArrayContent> GetFormDataByteArrayContent(NameValueCollection collection) { List<ByteArrayContent> list = new List<ByteArrayContent>(); foreach (var key in collection.AllKeys) { var dataContent = new ByteArrayContent(Encoding.UTF8.GetBytes(collection[key])); dataContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { Name = key }; list.Add(dataContent); } return list; }然后提交Api部分的代码如下(如需完整代码,请至底部点击源代码下载链接)
using (HttpClient client = new HttpClient()) { client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/" + this.cmbResponseContentType.Text.ToLower()));//设定要响应的数据格式 using (var content = new MultipartFormDataContent())//表明是通过multipart/form-data的方式上传数据 { var formDatas = this.GetFormDataByteArrayContent(this.GetNameValueCollection(this.gv_FormData));//获取键值集合对应的ByteArrayContent集合 var files = this.GetFileByteArrayContent(this.GetHashSet(this.gv_File));//获取文件集合对应的ByteArrayContent集合 Action<List<ByteArrayContent>> act = (dataContents) => {//声明一个委托,该委托的作用就是将ByteArrayContent集合加入到MultipartFormDataContent中 foreach (var byteArrayContent in dataContents) { content.Add(byteArrayContent); } }; act(formDatas);//执行act act(files);//执行act try { var result = client.PostAsync(this.txtUrl.Text, content).Result;//post请求 this.txtResponse.Text = result.Content.ReadAsStringAsync().Result;//将响应结果显示在文本框内 } catch (Exception ex) { this.txtResponse.Text = ex.ToString();//将异常信息显示在文本框内 } } }
2、WebAPI部分
其实WebAPI这部分真的没什么,完全是参考了国外大牛的代码,不过某些不明了的地方在方法内有备注,有时间会去研究下如何才能实现无需保存文件至硬盘,即可获取相应的数据流
[HttpPost] public async Task<Dictionary<string, string>> Post(int id = 0) { if (!Request.Content.IsMimeMultipartContent()) { throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); } Dictionary<string, string> dic = new Dictionary<string, string>(); string root = HttpContext.Current.Server.MapPath("~/App_Data");//指定要将文件存入的服务器物理位置 var provider = new MultipartFormDataStreamProvider(root); try { // Read the form data. await Request.Content.ReadAsMultipartAsync(provider); // This illustrates how to get the file names. foreach (MultipartFileData file in provider.FileData) {//接收文件 Trace.WriteLine(file.Headers.ContentDisposition.FileName);//获取上传文件实际的文件名 Trace.WriteLine("Server file path: " + file.LocalFileName);//获取上传文件在服务上默认的文件名 }//TODO:这样做直接就将文件存到了指定目录下,暂时不知道如何实现只接收文件数据流但并不保存至服务器的目录下,由开发自行指定如何存储,比如通过服务存到图片服务器 foreach (var key in provider.FormData.AllKeys) {//接收FormData dic.Add(key, provider.FormData[key]); } } catch { throw; } return dic; }
源代码下载,运行Demo时请先调试服务端,然后开启客户端,如果缺少HttpClient对应的dll,请通过NuGet下载
相关文章推荐
- WebAPI通过multipart/form-data方式同时上传文件以及数据(含HttpClient上传Demo)
- WebAPI通过multipart/form-data方式同时上传文件以及数据(含HttpClient上传Demo)
- WebAPI通过multipart/form-data方式同时上传文件以及数据(含HttpClient上传Demo)
- Multipart/form-data POST文件上传详解 理论 简单的HTTP POST 大家通过HTTP向服务器发送POST请求提交数据,都是通过form表单提交的,代码如下: <form me
- HttpClient 4.3.6 使用MultipartEntityBuilder实现类似form表单提交方式的文件上传
- WebAPI通过multipart/form-data方式接收文件时由开发自行决定如何保存文件
- http以post方式上传一个文件,构造其请求头和消息报文 application/x-www-form-urlencoded multipart/form-data
- jQuery利用XMLHttpRequest()和FormData()实现同时上传文件和数据
- spring mvc源码-》MultipartReques类-》主要是对文件上传进行的处理,在上传文件时,编码格式为enctype="multipart/form-data"格式,以二进制形式提交数据,提交方式为post方式。
- httpClient 使用multipart/form-data 类型上传文件及表单
- android向服务器上传multipart/form-data文件(upload using multipart post using httpclient in android)
- Http multipart/form-data多参数Post方式上传数据
- multipart/form-data方式上传text以及文件,类似微博发照片
- 通过 http 协议上传文件(rfc1867协议概述) multipart/form-data;boundary 解释
- 当form里增加enctype="multipart/form-data"时,上传文件与其他表单数据的研究
- 在Android上通过模拟HTTP multipart/form-data请求协议信息实现图片上传
- 在 Android 上通过模拟 HTTP multipart/form-data 请求协议信息实现图片上传
- HTTP multipart/form-data 上传方式说明
- 用xmlhttp将html的数据打包成multipart/form-data格式,实现异步上传文件功能
- 用xmlhttp将html的数据打包成multipart/form-data格式,实现异步上传文件功能[转]