webapi读取上传的文件流

时间:2021-07-17 13:31:40

逻辑说明

这里未引用System.Web.Mvc。
主要使用MultipartMemoryStreamProvider对象从Request中获取文件流。

var provider = new MultipartMemoryStreamProvider();
await Request.Content.ReadAsMultipartAsync(provider);
var items = provider.Contents.Where(c => c.Headers.ContentDisposition.FileName != null);

这里读取到的是所有带有文件名的http内容。

完整代码

扩展ApiController方法。

public static class ApiExtensions
{
    public async static Task<FormFileCollection> ReadFileCollectionAsync(this ApiController apiController)
    {
        var provider = new MultipartMemoryStreamProvider();
        await apiController.Request.Content.ReadAsMultipartAsync(provider);
        var items = provider.Contents.Where(c => c.Headers.ContentDisposition.FileName != null);
        FormFileCollection files = new FormFileCollection();
        foreach (var item in items)
        {
            var disposition = item.Headers.ContentDisposition;
            FormFile file = new FormFile(disposition.Name.Trim('"'), disposition.FileName.Trim('"'), item.Headers.ContentType.MediaType, await item.ReadAsStreamAsync(), item.Headers.ContentLength ?? 0);
            files.Add(file);
        }
        return files;
    }

    public static FormFileCollection ReadFileCollection(this ApiController apiController)
    {
        using (var t = ReadFileCollectionAsync(apiController))
        {
            t.Wait();
            return t.Result;
        }
    }
}

使用方法:
webapi读取上传的文件流

public IHttpActionResult Upload()
{
    var dir = "/upload/file";
    var dirPath = HostingEnvironment.MapPath(dir);
    if (!Directory.Exists(dirPath))
    {
        Directory.CreateDirectory(dirPath);
    }
    var files = this.ReadFileCollection();
    var fileA = files["filea"];
    fileA.SaveAs(Path.Combine(dirPath, fileA.FileName));
    var fileD = files["filed"];
    fileD.SaveAs(Path.Combine(dirPath, fileD.FileName));
    return Ok();
}

FormFile类:

public class FormFile
{
    public FormFile(string name, string fileName, string contentType, Stream stream, long size)
    {
        this.Name = name;
        this.FileName = fileName;
        this.ContentType = contentType;
        this.Stream = stream;
        this.Size = size;
    }

    public string Name { get; private set; }
    public string FileName { get; private set; }
    public string ContentType { get; private set; }
    public long Size { get; private set; }
    public Stream Stream { get; private set; }

    public virtual void SaveAs(string filename)
    {
        using (var fileStream = new FileStream(filename, FileMode.Create))
        {
            byte[] buffer = new byte[4096];
            while (true)
            {
                int num = this.Stream.Read(buffer, 0, buffer.Length);
                if (num == 0)
                {
                    break;
                }
                fileStream.Write(buffer, 0, num);
            }
            fileStream.Flush();
        }
    }
}

FormFileCollection类:

public class FormFileCollection : IEnumerable<FormFile>
{
    readonly List<FormFile> files = new List<FormFile>();
    public int Count => files.Count;

    public FormFile this[int index]
    {
        get { return files[index]; }
    }

    public FormFile this[string index]
    {
        get { return files.Where(f => f.Name == index).FirstOrDefault(); }
    }

    public void Add(FormFile item)
    {
        files.Add(item);
    }

    public void AddRange(IEnumerable<FormFile> items)
    {
        files.AddRange(items);
    }

    public IEnumerator<FormFile> GetEnumerator()
    {
        return files.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}