Reputation: 2119
Overview: Uploading an Excel spreadsheet to azure blob storage via dotnet core 2.0 MVC. The error occurs when trying to stream the file so that it can be saved into storage. using (var stream = new FileStream(file.FileName, FileMode.Open))
(code below - _employerFileAzureService.SaveBlobAsync).
I've reviewed several SO questions relating to this but couldn't find a solution from them.
I've been able to verify the following:
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} ");
}
}
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);
...
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;
}
}
Upvotes: 3
Views: 3160
Reputation: 161
I suspect it might be because you're trying to construct a FileStream out of file.FileName, which I think is just the name or path of the original file from the client's POV. You will have to work with the IFormFile's stream instead.
You can try copying the stream to a temporary file on the web server first, as shown in the example at: https://learn.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads
like so:
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);
}
Or you might be able to pass the stream on directly using file.OpenReadStream()
Upvotes: 9