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

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

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

  • 选择的文件正在从浏览器发送到 Controller
  • blob 容器已正确创建 (C#)

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

    Controller 调用
      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;
            }
        }
    

    最佳答案

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

    您可以先尝试将流复制到 Web 服务器上的临时文件,如示例所示: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() 传递流

    关于c# - 将 excel 上传到 azure blob 无法流式传输 IFormFile,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47775934/

    10-11 08:33