【问题标题】:Upload excel to azure blob fails streaming IFormFile将 excel 上传到 azure blob 流式传输 IFormFile 失败
【发布时间】:2018-05-26 08:01:11
【问题描述】:

概述:通过 dotnet core 2.0 MVC 将 Excel 电子表格上传到 Azure Blob 存储。尝试流式传输文件以便将其保存到存储中时会发生错误。 using (var stream = new FileStream(file.FileName, FileMode.Open))(下面的代码 - _employerFileAzureService.SaveBlobAsync)。

我已经查看了几个与此相关的 SO 问题,但无法从中找到解决方案。

我已经能够验证以下内容:

  • 所选文件正在从浏览器发送到控制器
  • blob 容器已正确创建 (C#)

错误

  Could not find file 'C:\dev\tfs\Admin.Web\employer-bad.test.xlsx'.

控制器调用

  public async Task<IActionResult> Upload(IList<IFormFile> files, CancellationToken cancellationToken)
    {
        var result = new UploadResultViewModel();
        var processResult = new FileProcessingResult();

        var errorMessage = new StringBuilder();
        var fileName = string.Empty;
        var withError = false;

        foreach (var file in files)
        {
            try
            {
                fileName = file.FileName;
                processResult =  await ProcessUploadFiledAsync(file, cancellationToken);
            }
            catch (Exception e)
            {
                _logger.LogError(e, "Error processing uploaded xslx");
                errorMessage.Append($"File: {fileName} errored. Error: {e.Message}");
                ModelState.AddModelError("", $"Error uploading file: {fileName} ");

            }
        }

在容器中设置 blob(失败 _employerFileAzureService.SaveBlobAsync)

   private async Task<FileProcessingResult> ProcessUploadFiledAsync(IFormFile file, CancellationToken cancellationToken)
    {
        var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Value.Trim('"');
        fileName = RandomizeFileName(fileName);

        var eins = new Dictionary<string, string>();
        var result = await _employerFileAzureService.SaveBlobAsync(fileName, file);
   ...

_employerFileAzureService.SaveBlobAsync

  public async Task<string> SaveBlobAsync(string fileName, IFormFile file)
    {
        try
        {
            var container = await _azureStorageConfigurator.GetBlobContainerAsync();
            var blobBlock = container.GetBlockBlobReference(fileName);

            using (var stream = new FileStream(file.FileName, FileMode.Open))
            {
                await blobBlock.UploadFromStreamAsync(stream);
            }

            var blobUrl = blobBlock.Uri.AbsolutePath;

            return $"{_azureStorageConfigurator.BaseStorageUri}{blobUrl}";
        }
        catch (Exception ex)
        {
            _logger.LogError($"*** Error Saving to storage: {ex.Message}");
            throw;
        }
    }

【问题讨论】:

    标签: c# azure .net-core azure-blob-storage


    【解决方案1】:

    我怀疑这可能是因为您试图从 file.FileName 构造一个 FileStream,我认为这只是来自客户端 POV 的原始文件的名称或路径。您将不得不使用 IFormFile 的流。

    您可以先尝试将流复制到网络服务器上的临时文件中,如示例所示:https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads

    像这样:

    var tempPath = Path.GetTempFileName();
    
    using (var stream = new FileStream(tempPath, FileMode.Create)){
        await file.CopyToAsync(stream);
    }
    using (var stream = new FileStream(tempPath, FileMode.Open)){
        await blobBlock.UploadFromStreamAsync(stream);
    }
    

    或者您可以直接使用 file.OpenReadStream() 传递流

    【讨论】:

    • @Michael_Jagroep 这起到了作用,但是,使用本地温度来暂缓一切,但OpenReadStream 是要走的路,现在它很活泼。非常感谢!
    • 绝对使用 OpenReadStream。请注意它返回 Func ,智能感知变得愚蠢,因此请确保您通过 using 块正确使用它。
    猜你喜欢
    • 1970-01-01
    • 2012-04-14
    • 1970-01-01
    • 2013-08-21
    • 2019-05-26
    • 2019-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多