逻辑说明
这里未引用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; } } }
使用方法:
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(); } }