在 c# 中从 Windows azure 中删除一个 blob
Delete a blob from Windows azure in c#
我有将 blob 插入存储的代码,并允许用户查看 blob 列表和单个 blob。但是,我现在无法删除 blob,出现的错误是
"An exception of type 'System.ServiceModel.FaultException`1' occurred in System.ServiceModel.ni.dll but was not handled in user code. Additional information: The remote server returned an error: (404) Not Found."
WCF 服务中的代码是
public void DeleteBlob(string guid, string uri)
{
//create the storage account with shared access key
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(accountDetails);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference(guid);
CloudBlockBlob blob = container.GetBlockBlobReference(uri);
blob.DeleteIfExists();
}
然后我通过 SOAP 服务在移动客户端应用程序中访问它,例如:
private void mnuDelete_Click(object sender, EventArgs e)
{
MessageBoxResult message = MessageBox.Show("Are you sure you want to delete this image?", "Delete", MessageBoxButton.OKCancel);
if (message == MessageBoxResult.OK)
{
Service1Client svc = new Service1Client();
svc.DeleteBlobCompleted += new EventHandler<AsyncCompletedEventArgs>(svc_DeleteBlobCompleted);
svc.DeleteBlobAsync(container, uri);
}
}
void svc_DeleteBlobCompleted(object sender, AsyncCompletedEventArgs e)
{
if (e.Error == null) {
NavigationService.Navigate(new Uri("/Pages/albums.xaml", UriKind.Relative));
}
else {
MessageBox.Show("Unable to delete this photo at this time", "Error", MessageBoxButton.OK);
}
}
我也首先使用 SAS 令牌来保存 blob - 我不知道这是否有所作为?
在 Azure 存储客户端库 4.0 中,我们更改了 Get*Reference 方法以仅接受相对地址。因此,如果您使用的是最新的库并且参数 "uri" 是绝对地址,您应该将其更改为 blob 名称或者您应该使用 CloudBlockBlob constructor that takes an Uri and a StorageCredentials 对象。
请在我们的 GitHub repository 中查看所有此类重大更改。
我在 ASP.NET 核心 MVC 网络应用程序 (v1.1.3) 中使用 WindowsAzure.Storage (v8.1.4)。
我的 Web 应用程序具有图像裁剪和调整大小功能,因此我决定使用 Azure Blob 存储来存储原始(用户上传)图片和裁剪后(调整大小后)的图片。
即使您使用带有绝对 uri 的 CloudBlockBlob
构造函数,也要记住一件重要的事情是您仍然需要将存储 帐户凭据 传递到CloudBlockBlob
构造函数。
public class AzureBlobStorageService : IBlobStorageService
{
private readonly AzureBlobConnectionConfigurations _azureBlobConnectionOptions;
private readonly CloudStorageAccount _storageAccount;
private readonly CloudBlobClient _blobClient;
public AzureBlobStorageService(IOptions<AzureBlobConnectionConfigurations> azureBlobConnectionAccessor)
{
_azureBlobConnectionOptions = azureBlobConnectionAccessor.Value;
_storageAccount = CloudStorageAccount.Parse(_azureBlobConnectionOptions.StorageConnectionString);
_blobClient = _storageAccount.CreateCloudBlobClient();
}
public async Task<Uri> UploadAsync(string containerName, string blobName, IFormFile image)
{
...
}
public async Task<Uri> UploadAsync(string containerName, string blobName, byte[] imageBytes)
{
...
}
public async Task<byte[]> GetBlobByUrlAsync(string url, bool deleteAfterFetch = false)
{
// This works
var blockBlob = new CloudBlockBlob(new Uri(url), _storageAccount.Credentials);
// Even this will fail
//var blockBlob = new CloudBlockBlob(new Uri(url));
await blockBlob.FetchAttributesAsync();
byte[] arr = new byte[blockBlob.Properties.Length];
await blockBlob.DownloadToByteArrayAsync(arr, 0);
if (deleteAfterFetch)
{
await blockBlob.DeleteIfExistsAsync();
}
return arr;
}
private async Task<CloudBlobContainer> CreateContainerIfNotExistAsync(string containerName)
{
var container = _blobClient.GetContainerReference(containerName);
if (!await container.ExistsAsync())
{
await container.CreateAsync();
await container.SetPermissionsAsync(new BlobContainerPermissions
{
PublicAccess = BlobContainerPublicAccessType.Blob
});
}
return container;
}
}
希望对您有所帮助。
在 Azure Storage Client Library 4.0 中,get Reference 方法必须更改为接受相对地址,而不接受其他任何内容。所以,这不支持更早的库,
您应该将其更改为 blob 名称,或者您应该使用采用 Uri 和 StorageCredentials 对象的 CloudBlockBlob 构造函数。
我有将 blob 插入存储的代码,并允许用户查看 blob 列表和单个 blob。但是,我现在无法删除 blob,出现的错误是
"An exception of type 'System.ServiceModel.FaultException`1' occurred in System.ServiceModel.ni.dll but was not handled in user code. Additional information: The remote server returned an error: (404) Not Found."
WCF 服务中的代码是
public void DeleteBlob(string guid, string uri)
{
//create the storage account with shared access key
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(accountDetails);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference(guid);
CloudBlockBlob blob = container.GetBlockBlobReference(uri);
blob.DeleteIfExists();
}
然后我通过 SOAP 服务在移动客户端应用程序中访问它,例如:
private void mnuDelete_Click(object sender, EventArgs e)
{
MessageBoxResult message = MessageBox.Show("Are you sure you want to delete this image?", "Delete", MessageBoxButton.OKCancel);
if (message == MessageBoxResult.OK)
{
Service1Client svc = new Service1Client();
svc.DeleteBlobCompleted += new EventHandler<AsyncCompletedEventArgs>(svc_DeleteBlobCompleted);
svc.DeleteBlobAsync(container, uri);
}
}
void svc_DeleteBlobCompleted(object sender, AsyncCompletedEventArgs e)
{
if (e.Error == null) {
NavigationService.Navigate(new Uri("/Pages/albums.xaml", UriKind.Relative));
}
else {
MessageBox.Show("Unable to delete this photo at this time", "Error", MessageBoxButton.OK);
}
}
我也首先使用 SAS 令牌来保存 blob - 我不知道这是否有所作为?
在 Azure 存储客户端库 4.0 中,我们更改了 Get*Reference 方法以仅接受相对地址。因此,如果您使用的是最新的库并且参数 "uri" 是绝对地址,您应该将其更改为 blob 名称或者您应该使用 CloudBlockBlob constructor that takes an Uri and a StorageCredentials 对象。
请在我们的 GitHub repository 中查看所有此类重大更改。
我在 ASP.NET 核心 MVC 网络应用程序 (v1.1.3) 中使用 WindowsAzure.Storage (v8.1.4)。
我的 Web 应用程序具有图像裁剪和调整大小功能,因此我决定使用 Azure Blob 存储来存储原始(用户上传)图片和裁剪后(调整大小后)的图片。
即使您使用带有绝对 uri 的 CloudBlockBlob
构造函数,也要记住一件重要的事情是您仍然需要将存储 帐户凭据 传递到CloudBlockBlob
构造函数。
public class AzureBlobStorageService : IBlobStorageService
{
private readonly AzureBlobConnectionConfigurations _azureBlobConnectionOptions;
private readonly CloudStorageAccount _storageAccount;
private readonly CloudBlobClient _blobClient;
public AzureBlobStorageService(IOptions<AzureBlobConnectionConfigurations> azureBlobConnectionAccessor)
{
_azureBlobConnectionOptions = azureBlobConnectionAccessor.Value;
_storageAccount = CloudStorageAccount.Parse(_azureBlobConnectionOptions.StorageConnectionString);
_blobClient = _storageAccount.CreateCloudBlobClient();
}
public async Task<Uri> UploadAsync(string containerName, string blobName, IFormFile image)
{
...
}
public async Task<Uri> UploadAsync(string containerName, string blobName, byte[] imageBytes)
{
...
}
public async Task<byte[]> GetBlobByUrlAsync(string url, bool deleteAfterFetch = false)
{
// This works
var blockBlob = new CloudBlockBlob(new Uri(url), _storageAccount.Credentials);
// Even this will fail
//var blockBlob = new CloudBlockBlob(new Uri(url));
await blockBlob.FetchAttributesAsync();
byte[] arr = new byte[blockBlob.Properties.Length];
await blockBlob.DownloadToByteArrayAsync(arr, 0);
if (deleteAfterFetch)
{
await blockBlob.DeleteIfExistsAsync();
}
return arr;
}
private async Task<CloudBlobContainer> CreateContainerIfNotExistAsync(string containerName)
{
var container = _blobClient.GetContainerReference(containerName);
if (!await container.ExistsAsync())
{
await container.CreateAsync();
await container.SetPermissionsAsync(new BlobContainerPermissions
{
PublicAccess = BlobContainerPublicAccessType.Blob
});
}
return container;
}
}
希望对您有所帮助。
在 Azure Storage Client Library 4.0 中,get Reference 方法必须更改为接受相对地址,而不接受其他任何内容。所以,这不支持更早的库,
您应该将其更改为 blob 名称,或者您应该使用采用 Uri 和 StorageCredentials 对象的 CloudBlockBlob 构造函数。