Azure Blob Upload 在 ASP .Net Core 应用程序中不起作用



我正在尝试将文件上传到Asp .Net Core中的Azure blob存储。一切似乎都在工作,但没有上传文件。这是我的代码片段:

var blobReference = GetBlobReference();
rawData.Position = 0;
//  var result = blobReference.UploadFromStreamAsync(rawData);
var result = blobReference.UploadFromFileAsync("C:\users\tjaartb\Downloads\DebitOrderMandate.pdf");
result.GetAwaiter().GetResult();
var blobPath = blobReference.Uri.ToString();

发生了什么事情?

调试器单步执行result.GetAwaiter().GetResult(),不会发生异常。在GetResult()调用后检查resultTask 变量显示任务状态为RanToCompletion,异常属性为空。我的 Blob 容器是在前面的代码中成功创建的,指示与 Blob 存储的连接成功。GetResult()立即完成,所以似乎什么都没发生。

我检查过的事情

  • rawData是填充了文件数据的MemoryStream。使用注释行尝试通过流上传也不成功。
  • 与 Azure 的连接正在工作。
  • 文件路径存在。
  • 没有引发任何异常。
  • 我的调试窗口输出中唯一的东西是Started Thread <ThreadNumber>
  • 在对blobReference.UploadFromFileAsync()的调用中放置无效路径会按预期引发FileNotFoundException
  • 我曾尝试将我的项目从netcoreapp2.1降级为netcoreapp2.0,但没有成功。

以下代码与WindowsAzure.Storage - Version 9.3.1包适用于Asp Net Core 2.1。

public class AzureBlobModel
{
public string FileName { get; set; }
public long? FileSize { get; set; }
public Stream Stream { get; set; }
public string ContentType { get; set; }
}
public interface IImageStore
{
Task<string> SaveDocument(Stream documentStream);
Task<bool> DeleteDocument(string imageId);
Task<AzureBlobModel> DownloadDocument(string documentId, string fileName);
string UriFor(string documentId);
}
public class ImageStore : IImageStore
{
CloudBlobClient blobClient;
string baseUri = "https://xxxxx.blob.core.windows.net/";
public ImageStore()
{
var credentials = new StorageCredentials("xxxxx accountName xxxxx", "xxxxx keyValue xxxxx");
blobClient = new CloudBlobClient(new Uri(baseUri), credentials);
}
public async Task<string> SaveDocument(Stream documentStream)
{
var documentId = Guid.NewGuid().ToString();
var container = blobClient.GetContainerReference("xxxxx container xxxxx");
var blob = container.GetBlockBlobReference(documentId);
await blob.UploadFromStreamAsync(documentStream);
return documentId;
}
public async Task<bool> DeleteDocument(string documentId)
{
var container = blobClient.GetContainerReference("xxxxx container xxxxx");
var blob = container.GetBlockBlobReference(documentId);
bool blobExisted = await blob.DeleteIfExistsAsync();
return blobExisted;
}
public async Task<AzureBlobModel> DownloadDocument(string documentId, string fileName)
{
var container = blobClient.GetContainerReference("xxxxx container xxxxx");
var blob = container.GetBlockBlobReference(documentId);
var doc = new AzureBlobModel()
{
FileName = fileName,
Stream = new MemoryStream(),
};
doc.Stream = await blob.OpenReadAsync();
doc.ContentType = blob.Properties.ContentType;
doc.FileSize = blob.Properties.Length;
return doc;
}
public string UriFor(string documentId)
{
var sasPolicy = new SharedAccessBlobPolicy
{
Permissions = SharedAccessBlobPermissions.Read,
SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-15),
SharedAccessExpiryTime = DateTime.UtcNow.AddDays(1)
};
var container = blobClient.GetContainerReference("xxxxx container xxxxx");
var blob = container.GetBlockBlobReference(documentId);
var sas = blob.GetSharedAccessSignature(sasPolicy);
return $"{baseUri}xxxxx container xxxxx/{documentId}{sas}";
}
}
public class DocForCreationDto
{
public IFormFile File { get; set; }
// other properties ...
}
// On the controller
[HttpPost]
public async Task<IActionResult> Upload([FromForm]DocForCreationDto docForCreationDto)
{
if (docForCreationDto.File == null || !ModelState.IsValid)
{
return new UnprocessableEntityObjectResult(ModelState);
}
string documentId = string.Empty;
using (var stream = docForCreationDto.File.OpenReadStream())
{
documentId = await _imageStore.SaveDocument(stream);
}
if (documentId != string.Empty)
{
// upload ok ...
//some business logic here ...
return Ok();
}
return BadRequest("xxx error xxx");
}
[HttpGet("{documentId}", Name = "GetDocument")]
public async Task<IActionResult> GetDocument(int documentId)
{
var doc = await _imageStore.DownloadDocument(documentId, "output filename");
return File(doc.Stream, doc.ContentType, doc.FileName);
}
// On Startup - ConfigureServices
services.AddSingleton<IImageStore, ImageStore>();

/前缀添加到 Blob 名称会导致无提示失败。文件根本不上传。删除/前缀解决了问题。

使用.NET Core 2.1和WindowsAzure.Storage 9.3.2,所有方法现在都是异步的。 如果不等待所有异步方法调用,则可能会遇到静默失败。 问题下面的评论帮助我弄清楚了这一点。

我在该方法中实现的接口是没有异步签名的更大生态系统的一部分。重构它需要付出很多努力。

您可以使用Wait()替换await以实现异步签名。请参考以下代码:

CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connection);
CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();
var cloudBlobContainer = cloudBlobClient.GetContainerReference("containername");
CloudBlockBlob blob = cloudBlobContainer.GetBlockBlobReference("DebitOrderMandate.pdf");
using (var fileStream = System.IO.File.OpenRead("C:\users\tjaartb\Downloads\DebitOrderMandate.pdf"))
{
blob.UploadFromStreamAsync(fileStream).Wait();
}

相关内容

最新更新