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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tiana0/article/details/64496069

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);
    }      
}

猜你喜欢

转载自blog.csdn.net/tiana0/article/details/64496069