[英]Azure Blob Upload not working in ASP .Net Core Application
我正在嘗試將文件上傳到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()
調用之后檢查result
任務變量顯示任務狀態為RanToCompletion
且異常屬性為空。 我的blob容器在早期代碼中成功創建,表明與blob存儲的連接成功。 GetResult()
立即完成,所以似乎沒有任何事情發生。
rawData
是一個填充了文件數據的MemoryStream
。 使用注釋行嘗試通過流上傳也不成功。 Started Thread <ThreadNumber>
blobReference.UploadFromFileAsync()
的調用中放置無效路徑會按預期引發FileNotFoundException
。 netcoreapp2.1
將我的項目降級到netcoreapp2.0
netcoreapp2.1
沒有成功。 以下代碼與WindowsAzure.Storage - 版本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>();
我在該方法中實現的接口是沒有異步簽名的更大生態系統的一部分。 重構它需要付出很多努力。
您可以使用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();
}
在Blob名稱中添加/
前綴會導致靜默失敗。 該文件根本不上傳。 刪除/
前綴修復了問題。
使用.NET Core 2.1和WindowsAzure.Storage 9.3.2,所有方法現在都是異步的。 如果不等待所有異步方法調用,則可能會出現靜默失敗。 這個問題下面的評論幫我解決了這個問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.