System.InvalidCastException in Renaming Azure Container



我正在尝试重命名 azure blob 存储中的容器。我能够成功重命名容器。但我注意到在一些情况下,在某些过程中。我遇到了一些错误。

这是错误消息。

System.InvalidCastException: '无法强制转换类型的对象 "Microsoft.WindowsAzure.Storage.Blob.CloudBlobDirectory"键入 'Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob'.">

下面是我的代码。

string ContainerName = "old-container-name";
string NewContainerName = "new-container-name";
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference(ContainerName);
CloudBlobContainer destcontainer = blobClient.GetContainerReference(NewContainerName);
destcontainer.CreateIfNotExists(BlobContainerPublicAccessType.Blob);
IEnumerable<IListBlobItem> IE = container.ListBlobs(blobListingDetails: BlobListingDetails.Metadata);
foreach (IListBlobItem item in IE)
{
CloudBlockBlob blob = (CloudBlockBlob)item;
CloudBlockBlob destBlob = destcontainer.GetBlockBlobReference(blob.Name);
destBlob.StartCopyAsync(new Uri(GetSharedAccessUri(blob.Name, container)));
}

我收到此行的错误:

CloudBlockBlob blob = (CloudBlockBlob)item;

你们有解决这个问题吗?关于如何解决此问题的任何提示?

收到此错误的原因是列出 blob 的方式。

IEnumerable<IListBlobItem> IE = container.ListBlobs(blobListingDetails: BlobListingDetails.Metadata);

上面的代码行将列出 blob 和虚拟文件夹。虚拟文件夹由CloudBlobDirectory表示。由于您尝试将类型为CloudBlockBlob的对象转换为CloudBlobDirectory,因此会出现此异常。

若要列出 Blob 容器中的所有 Blob,请使用以下替代ListBlobs方法:https://learn.microsoft.com/en-us/dotnet/api/microsoft.azure.storage.blob.cloudblobcontainer.listblobs?view=azure-dotnet-legacy。

您需要为useFlatBlobListing参数传递true。然后,它将仅返回 Blob,而不返回虚拟文件夹。

  • 在转换之前检查item的类型。
  • 你必须await你的Task.
  • 始终首选异步 API。不要混合使用非异步和异步 API(这确实意味着使用下面也定义的自定义ListBlobsAsync方法,因为没有单一的ListBlobsAsync方法(:

async Task CopyBlobsAsync()
{
const String ContainerName    = "old-container-name";
const String NewContainerName = "new-container-name";
CloudStorageAccount storageAccount = CloudStorageAccount.Parse( CloudConfigurationManager.GetSetting("StorageConnectionString") );
CloudBlobClient     blobClient     = storageAccount.CreateCloudBlobClient();
CloudBlobContainer  container      = blobClient.GetContainerReference( ContainerName );
CloudBlobContainer  destcontainer  = blobClient.GetContainerReference( NewContainerName );
await destcontainer.CreateIfNotExistsAsync( BlobContainerPublicAccessType.Blob );
List<IListBlobItem> blobs = await ListBlobsAsync( container ).ConfigureAwait(false);
List<Task>          tasks = new List<Task>();
foreach( IListBlobItem item in blobs )
{
if( item is CloudBlockBlob blob )
{
CloudBlockBlob destBlob = destcontainer.GetBlockBlobReference( blob.Name );
Uri destUri = new Uri( GetSharedAccessUri( blob.Name, container ) );
Task task = destBlob.StartCopyAsync( destUri  );
tasks.Add( task );
}
}
await Task.WhenAll( tasks ).ConfigureAwait(false);
}
// From https://ahmet.im/blog/azure-listblobssegmentedasync-listcontainerssegmentedasync-how-to/
async Task<List<IListBlobItem> ListBlobsAsync( CloudBlobContainer container )
{
BlobContinuationToken continuationToken = null;
List<IListBlobItem> results = new List<IListBlobItem>();
do
{
var response = await ListBlobsSegmentedAsync( continuationToken );
continuationToken = response.ContinuationToken;
results.AddRange( response.Results );
}
while( continuationToken != null );
return results;
}

最新更新