C# 上载/获取Blob-使用.NET Core中的Azure存储帐户创建容器
我已经对此进行了相当长一段时间的研究,我一直致力于从.NET核心webapi对我的存储帐户执行基本操作 你应该知道以下几点:C# 上载/获取Blob-使用.NET Core中的Azure存储帐户创建容器,c#,.net-core,azure-storage-blobs,C#,.net Core,Azure Storage Blobs,我已经对此进行了相当长一段时间的研究,我一直致力于从.NET核心webapi对我的存储帐户执行基本操作 你应该知道以下几点: services.AddSingleton(x => new BlobServiceClient(config.GetValue<string>("AzureBlobStorage"))); private void GenerateSharedAccessKeyRequestHeader(string blobContainerN
services.AddSingleton(x => new BlobServiceClient(config.GetValue<string>("AzureBlobStorage")));
private void GenerateSharedAccessKeyRequestHeader(string blobContainerName, Stream content, string fileName, string contentType)
{
string storageKey = "key";
string storageAccount = "name";
string method = "PUT";
long contentLength = content.Length;
string requestUri = $"https://{storageAccount}.blob.core.windows.net/{blobContainerName}/{fileName}";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);
string now = DateTime.UtcNow.ToString("R");
request.Method = method;
request.ContentType = contentType;
request.ContentLength = contentLength;
request.Headers.Add("x-ms-version", "2015-12-11");
request.Headers.Add("x-ms-date", now);
request.Headers.Add("x-ms-blob-type", "BlockBlob");
request.Headers.Add("Authorization", AuthorizationHeader(method, now, request, storageAccount, storageKey, blobContainerName, fileName));
}
private string AuthorizationHeader(string method, string now, HttpWebRequest request, string storageAccount, string storageKey, string containerName, string blobName)
{
string headerResource = $"x-ms-blob-type:BlockBlob\nx-ms-date:{now}\nx-ms-version:2015-12-11";
string urlResource = $"/{storageAccount}/{containerName}/{blobName}";
string stringToSign = $"{method}\n\n\n{request.ContentLength}\n\n{request.ContentType}\n\n\n\n\n\n\n{headerResource}\n{urlResource}";
HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(storageKey));
string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
String AuthorizationHeader = String.Format("{0} {1}:{2}", "SharedKey", storageAccount, signature);
return AuthorizationHeader;
}
services.AddSingleton(x => new BlobServiceClient(config.GetValue<string>("AzureBlobStorage")));
private void GenerateSharedAccessKeyRequestHeader(string blobContainerName, Stream content, string fileName, string contentType)
{
string storageKey = "key";
string storageAccount = "name";
string method = "PUT";
long contentLength = content.Length;
string requestUri = $"https://{storageAccount}.blob.core.windows.net/{blobContainerName}/{fileName}";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);
string now = DateTime.UtcNow.ToString("R");
request.Method = method;
request.ContentType = contentType;
request.ContentLength = contentLength;
request.Headers.Add("x-ms-version", "2015-12-11");
request.Headers.Add("x-ms-date", now);
request.Headers.Add("x-ms-blob-type", "BlockBlob");
request.Headers.Add("Authorization", AuthorizationHeader(method, now, request, storageAccount, storageKey, blobContainerName, fileName));
}
private string AuthorizationHeader(string method, string now, HttpWebRequest request, string storageAccount, string storageKey, string containerName, string blobName)
{
string headerResource = $"x-ms-blob-type:BlockBlob\nx-ms-date:{now}\nx-ms-version:2015-12-11";
string urlResource = $"/{storageAccount}/{containerName}/{blobName}";
string stringToSign = $"{method}\n\n\n{request.ContentLength}\n\n{request.ContentType}\n\n\n\n\n\n\n{headerResource}\n{urlResource}";
HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(storageKey));
string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
String AuthorizationHeader = String.Format("{0} {1}:{2}", "SharedKey", storageAccount, signature);
return AuthorizationHeader;
}
上传blob的过程如下所示:
services.AddSingleton(x => new BlobServiceClient(config.GetValue<string>("AzureBlobStorage")));
private void GenerateSharedAccessKeyRequestHeader(string blobContainerName, Stream content, string fileName, string contentType)
{
string storageKey = "key";
string storageAccount = "name";
string method = "PUT";
long contentLength = content.Length;
string requestUri = $"https://{storageAccount}.blob.core.windows.net/{blobContainerName}/{fileName}";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);
string now = DateTime.UtcNow.ToString("R");
request.Method = method;
request.ContentType = contentType;
request.ContentLength = contentLength;
request.Headers.Add("x-ms-version", "2015-12-11");
request.Headers.Add("x-ms-date", now);
request.Headers.Add("x-ms-blob-type", "BlockBlob");
request.Headers.Add("Authorization", AuthorizationHeader(method, now, request, storageAccount, storageKey, blobContainerName, fileName));
}
private string AuthorizationHeader(string method, string now, HttpWebRequest request, string storageAccount, string storageKey, string containerName, string blobName)
{
string headerResource = $"x-ms-blob-type:BlockBlob\nx-ms-date:{now}\nx-ms-version:2015-12-11";
string urlResource = $"/{storageAccount}/{containerName}/{blobName}";
string stringToSign = $"{method}\n\n\n{request.ContentLength}\n\n{request.ContentType}\n\n\n\n\n\n\n{headerResource}\n{urlResource}";
HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(storageKey));
string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
String AuthorizationHeader = String.Format("{0} {1}:{2}", "SharedKey", storageAccount, signature);
return AuthorizationHeader;
}
IFormFile file = Request.Form.Files[0];
if (file == null)
{
return BadRequest();
}
string fileName = Guid.NewGuid().ToString().ToLower();
string containerName = blobContainerName.ToLower();
var result = await this.blobService.UploadBlobAsync(
containerName,
file.OpenReadStream(),
file.ContentType,
fileName);
var toReturn = result.AbsoluteUri;
return Ok(new { path = toReturn });
UploadBlobAsync
方法并传递参数。。到目前为止还不错
public async Task<Uri> UploadBlobAsync(string blobContainerName, Stream content, string contentType, string fileName)
{
var containerClient = GetContainerClient(blobContainerName); // <<<<< EXCEPTION
var blobClient = containerClient.GetBlobClient(fileName);
await blobClient.UploadAsync(content, new BlobHttpHeaders { ContentType = contentType });
return blobClient.Uri;
}
到目前为止,我得到这个例外的原因是显而易见的。。因为公共访问级别已禁用
Microsoft文档说明我需要生成一个共享访问密钥,该密钥以某种方式附加到我的请求中
这就是为什么我有另一个方法生成适当的请求头,如下所示:
services.AddSingleton(x => new BlobServiceClient(config.GetValue<string>("AzureBlobStorage")));
private void GenerateSharedAccessKeyRequestHeader(string blobContainerName, Stream content, string fileName, string contentType)
{
string storageKey = "key";
string storageAccount = "name";
string method = "PUT";
long contentLength = content.Length;
string requestUri = $"https://{storageAccount}.blob.core.windows.net/{blobContainerName}/{fileName}";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);
string now = DateTime.UtcNow.ToString("R");
request.Method = method;
request.ContentType = contentType;
request.ContentLength = contentLength;
request.Headers.Add("x-ms-version", "2015-12-11");
request.Headers.Add("x-ms-date", now);
request.Headers.Add("x-ms-blob-type", "BlockBlob");
request.Headers.Add("Authorization", AuthorizationHeader(method, now, request, storageAccount, storageKey, blobContainerName, fileName));
}
private string AuthorizationHeader(string method, string now, HttpWebRequest request, string storageAccount, string storageKey, string containerName, string blobName)
{
string headerResource = $"x-ms-blob-type:BlockBlob\nx-ms-date:{now}\nx-ms-version:2015-12-11";
string urlResource = $"/{storageAccount}/{containerName}/{blobName}";
string stringToSign = $"{method}\n\n\n{request.ContentLength}\n\n{request.ContentType}\n\n\n\n\n\n\n{headerResource}\n{urlResource}";
HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(storageKey));
string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
String AuthorizationHeader = String.Format("{0} {1}:{2}", "SharedKey", storageAccount, signature);
return AuthorizationHeader;
}
问题是我不确定在哪里注入这些请求头来上传我的blob或创建容器,甚至从我的存储帐户获取/列出/删除blob
public async Task<CustomBlobInfo> GetBlobAsync(string blobContainerName, string fileName)
{
var containerClient = GetContainerClient(blobContainerName);
var blobClient = containerClient.GetBlobClient(fileName);
var blobDownloadInfo = await blobClient.DownloadAsync();
return new CustomBlobInfo(blobDownloadInfo.Value.Content, blobDownloadInfo.Value.ContentType);
}
public async Task<IEnumerable<string>> ListBlobsAsync(string blobContainerName)
{
var containerClient = GetContainerClient(blobContainerName);
var items = new List<string>();
await foreach (var item in containerClient.GetBlobsAsync())
{
items.Add(item.Name);
}
return items;
}
public async Task DeleteBlobAsync(string blobContainerName, string fileName)
{
var containerClient = GetContainerClient(blobContainerName);
var blobClient = containerClient.GetBlobClient(fileName);
await blobClient.DeleteIfExistsAsync();
}
公共异步任务GetBlobAsync(字符串blobContainerName,字符串文件名)
{
var containerClient=GetContainerClient(blobContainerName);
var blobClient=containerClient.GetBlobClient(文件名);
var blobDownloadInfo=await blobClient.downloadsync();
返回新的CustomBlobInfo(blobDownloadInfo.Value.Content,blobDownloadInfo.Value.ContentType);
}
公共异步任务列表BlobAsync(字符串blobContainerName)
{
var containerClient=GetContainerClient(blobContainerName);
var items=新列表();
等待foreach(containerClient.GetBlobsAsync()中的变量项)
{
items.Add(item.Name);
}
退货项目;
}
公共异步任务DeleteBlobAsync(字符串blobContainerName,字符串文件名)
{
var containerClient=GetContainerClient(blobContainerName);
var blobClient=containerClient.GetBlobClient(文件名);
等待blobClient.DeleteIfExistsAsync();
}
这应该很容易,但由于某些原因,我已经在这方面困了好几天了。您的blob存储帐户设置为: 允许Blob公共访问设置为“禁用” 然后,您的代码将通过
publiccesstype.Blob
:
containerClient.CreateIfNotExists(PublicAccessType.Blob)
然后你会得到一个例外:
抛出一个异常,表示禁止公共访问
public async Task<Uri> UploadBlobAsync(string blobContainerName, Stream content, string contentType, string fileName)
{
var containerClient = GetContainerClient(blobContainerName); // <<<<< EXCEPTION
var blobClient = containerClient.GetBlobClient(fileName);
await blobClient.UploadAsync(content, new BlobHttpHeaders { ContentType = contentType });
return blobClient.Uri;
}
在我看来,解决方案是:
containerClient.CreateIfNotExists()代码>,或
嗨,斯蒂芬。。我不敢相信我错过了这个!!!!!!删除公共访问类型是问题所在。多谢各位much@GauravMantri伙计,我正在传递PublicAccessType,在禁用存储公共访问后,我完全忘记删除它。。用我的代码修复你的。。感谢斯蒂芬