webapi不使用MultipartFormDataStreamProvider上传multipart form-data数据的方法

Posted 三五月儿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webapi不使用MultipartFormDataStreamProvider上传multipart form-data数据的方法相关的知识,希望对你有一定的参考价值。

webapi开发中,经常会使用multipart/form-data方式来实现文件的上传。而网上流传甚广的就是下面这样一份代码。但是,这份代码有个问题,就是初始化MultipartFormDataStreamProvider类或者子类时,需要制定文件的保存路径。但是,有些应用场景是无法指定这个路径的,比如由于安全问题不允许直接进行文件的写入。有时候,甚至没必要指定这个路径,因为只需要读取传递过来的文件对应的byte数组即可。那么本文针对这种情况给出了一种解决方法。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;

namespace UploadApplication.Controllers

    public class UploadController : ApiController
    
        public async Task<HttpResponseMessage> Post()
        
            if (!Request.Content.IsMimeMultipartContent())
            
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
            
            string fileSaveLocation = HttpContext.Current.Server.MapPath("~/App_Data");
            CustomMultipartFormDataStreamProvider provider = new CustomMultipartFormDataStreamProvider(fileSaveLocation);
            List<string> files = new List<string>();
            Dictionary<string, string> dic = new Dictionary<string, string>();  
            try
            
                await Request.Content.ReadAsMultipartAsync(provider);
                foreach (MultipartFileData file in provider.FileData)
                //接收FileData
                    files.Add(Path.GetFileName(file.LocalFileName));
                
                foreach (var key in provider.FormData.AllKeys)  
                //接收FormData  
                    dic.Add(key, provider.FormData[key]);  
                  
                return Request.CreateResponse(HttpStatusCode.OK, files);
            
            catch (System.Exception e)
            
                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
            
        
    
    public class CustomMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
    
        public CustomMultipartFormDataStreamProvider(string path) : base(path)  
        public override string GetLocalFileName(HttpContentHeaders headers)
        
            return headers.ContentDisposition.FileName.Replace("\\"", string.Empty);
        
    

下面的代码直接从请求的Content中读取请求数据,得到MultipartMemoryStreamProvider对象,遍历该对象的Contents属性,可以得到包含上传文件及form表单数据的HttpContent对象。如何从Contents找到包含文件数据的HttpContent对象,可以根据HttpContent对象头部中对应的FileName属性来判断,这个需要和前端约定好,文件数据必须传入文件名称。

var multipartMemoryStreamProvider = await Request.Content.ReadAsMultipartAsync();
Dictionary<string, string> dic = new Dictionary<string, string>();
foreach (var content in multipartMemoryStreamProvider.Contents)

    if (!string.IsNullOrEmpty(content.Headers.ContentDisposition.FileName))
    
        using (Stream stream = await content.ReadAsStreamAsync())
        
            byte[] bytes = new byte[stream.Length];
            stream.Read(bytes, 0, bytes.Length);
        
    
    else
    
       string val = await content.ReadAsStringAsync();
       dic.Add(content.Headers.ContentDisposition.Name, val);
          

以上是关于webapi不使用MultipartFormDataStreamProvider上传multipart form-data数据的方法的主要内容,如果未能解决你的问题,请参考以下文章

WebAPI 2.2 不支持 substringof 函数

通过提供代理令牌处理来自 webapi 的长不记名令牌

如何修复 webAPI 中不正确的操作路由

URLrewrite后不允许AngularJS / c#WebAPI 405方法

vs2013使用webapi过程中遇到的问题

C#进阶系列——WebApi 接口返回值不困惑:返回值类型详解