批量媒体通过WebApi上载到Azure Blob存储

SB2*_*055 10 javascript c# azure azure-storage-blobs asp.net-web-api

我的网络应用程序目前允许用户使用以下方法一次一个地上传媒体:

var fd = new FormData(document.forms[0]);
fd.append("media", blob); // blob is the image/video
$.ajax({
    type: "POST",
    url: '/api/media',
    data: fd
})
Run Code Online (Sandbox Code Playgroud)

然后媒体被发布到WebApi控制器:

    [HttpPost, Route("api/media")]
    public async Task<IHttpActionResult> UploadFile()
    {
        if (!Request.Content.IsMimeMultipartContent("form-data"))
        {
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
        }

        string mediaPath = await _mediaService.UploadFile(User.Identity.Name, Request.Content);

        return Ok(mediaPath);
    }
Run Code Online (Sandbox Code Playgroud)

然后,它做了一些事情:

 public async Task<string> UploadFile(string username, HttpContent content)
 {
   var storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true);
   CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
   CloudBlobContainer imagesContainer = blobClient.GetContainerReference("container-" + user.UserId);
   var provider = new AzureStorageMultipartFormDataStreamProvider(imagesContainer);
   await content.ReadAsMultipartAsync(provider);
   var filename = provider.FileData.FirstOrDefault()?.LocalFileName;
   // etc
 }
Run Code Online (Sandbox Code Playgroud)

这对于单个上传非常有用,但是如何通过单个流操作返回上传文件名数组来修改此内容以支持多个文件的批量上传?关于此的文档/示例似乎很少.

public class AzureStorageMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
{
    private readonly CloudBlobContainer _blobContainer;
    private readonly string[] _supportedMimeTypes = { "images/png", "images/jpeg", "images/jpg", "image/png", "image/jpeg", "image/jpg", "video/webm" };

    public AzureStorageMultipartFormDataStreamProvider(CloudBlobContainer blobContainer) : base("azure")
    {
        _blobContainer = blobContainer;
    }

    public override Stream GetStream(HttpContent parent, HttpContentHeaders headers)
    {
        if (parent == null) throw new ArgumentNullException(nameof(parent));
        if (headers == null) throw new ArgumentNullException(nameof(headers));

        if (!_supportedMimeTypes.Contains(headers.ContentType.ToString().ToLower()))
        {
            throw new NotSupportedException("Only jpeg and png are supported");
        }

        // Generate a new filename for every new blob
        var fileName = Guid.NewGuid().ToString();

        CloudBlockBlob blob = _blobContainer.GetBlockBlobReference(fileName);

        if (headers.ContentType != null)
        {
            // Set appropriate content type for your uploaded file
            blob.Properties.ContentType = headers.ContentType.MediaType;
        }

        this.FileData.Add(new MultipartFileData(headers, blob.Name));

        return blob.OpenWrite();
    }
}
Run Code Online (Sandbox Code Playgroud)

Fra*_*rdo 2

假设您的AzureStorageMultipartFormDataStreamProvider类类似于本博客中提到的同一类,如果请求中有多个文件,那么实际上已经在处理多个文件。

因此,您需要做的就是更改您的UploadFile返回 aIEnumerable<string>并将您的控制器更改为mediaPath这样。

所以你的 MediaService 将有:

var filenames = provider.FileData.Select(x => x.LocalFileName).ToList(); ;
return filenames;
Run Code Online (Sandbox Code Playgroud)

你的控制器将有:

var mediaPaths = await _mediaService.UploadFile(User.Identity.Name, Request.Content);
return Ok(mediaPaths);
Run Code Online (Sandbox Code Playgroud)