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集合的代码
-
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;
- }
-
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())
- {
- var formDatas = this.GetFormDataByteArrayContent(this.GetNameValueCollection(this.gv_FormData));
- var files = this.GetFileByteArrayContent(this.GetHashSet(this.gv_File));
- Action<List<ByteArrayContent>> act = (dataContents) =>
- {
- foreach (var byteArrayContent in dataContents)
- {
- content.Add(byteArrayContent);
- }
- };
- act(formDatas);
- act(files);
- try
- {
- var result = client.PostAsync(this.txtUrl.Text, content).Result;
- 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
- {
-
- await Request.Content.ReadAsMultipartAsync(provider);
-
-
- foreach (MultipartFileData file in provider.FileData)
- {
- Trace.WriteLine(file.Headers.ContentDisposition.FileName);
- Trace.WriteLine("Server file path: " + file.LocalFileName);
- }
- foreach (var key in provider.FormData.AllKeys)
- {
- dic.Add(key, provider.FormData[key]);
- }
- }
- catch
- {
- throw;
- }
- return dic;
- }
csdn源代码下载,github源代码下载,运行Demo时请先调试服务端,然后开启客户端,如果缺少HttpClient对应的dll,请通过NuGet下载
PS:补充由服务端指定文件存储位置博客地址