3

I am having below method to copy data to destination storage blob

private static async Task MoveMatchingBlobsAsync(IEnumerable<ICloudBlob> sourceBlobRefs, 
           CloudBlobContainer sourceContainer, 
           CloudBlobContainer destContainer)
{
   foreach (ICloudBlob sourceBlobRef in sourceBlobRefs)
   {
      if (sourceBlobRef.Properties.ContentType != null)
      {
       // Copy the source blob
       CloudBlockBlob destBlob = destContainer.GetBlockBlobReference(sourceBlobRef.Name);

       try
       {
           //exception throwed here  - StartCopyAsync
           await destBlob.StartCopyAsync(new Uri(GetSharedAccessUri(sourceBlobRef.Name, sourceContainer))); /

           ICloudBlob destBlobRef = await destContainer.GetBlobReferenceFromServerAsync(sourceBlobRef.Name);
           while (destBlobRef.CopyState.Status == CopyStatus.Pending)
           {
                 Console.WriteLine($"Blob: {destBlobRef.Name}, Copied: {destBlobRef.CopyState.BytesCopied ?? 0} of  {destBlobRef.CopyState.TotalBytes ?? 0}");
                 await Task.Delay(500);
                 destBlobRef = await destContainer.GetBlobReferenceFromServerAsync(sourceBlobRef.Name);
            }
            Console.WriteLine($"Blob: {destBlob.Name} Complete");
          }
          catch (Exception e)
          {
               Console.WriteLine($"Blob: {destBlob.Name} Copy Failed");
           }
          }
        }
      }

I am getting below exception, there is no more information

The requested operation is not allowed in the current state of the entity

What may be the cause?

Here is my method to collect blob from the source location

  private static async Task<IEnumerable<ICloudBlob>> FindMatchingBlobsAsync(CloudBlobContainer blobContainer,string prefix, int maxrecords,int total)
    {
        List<ICloudBlob> blobList = new List<ICloudBlob>();
        BlobContinuationToken token = null;
        do
        {
            BlobResultSegment segment = await blobContainer.ListBlobsSegmentedAsync(prefix: prefix, useFlatBlobListing: true, BlobListingDetails.None, maxrecords, token, new BlobRequestOptions(), new OperationContext());
            token = segment.ContinuationToken;
            foreach (var item in segment.Results)
            {
                blobList.Add((ICloudBlob)item);
                if (blobList.Count > total) // total record count is configured
                    token = null;
            }
        } while ( token != null);
        return blobList;
    }

Here is my GetSharedAccessUri method which returns Uri without any issue

     private static string GetSharedAccessUri(string blobName, CloudBlobContainer container)
    {
        DateTime toDateTime = DateTime.Now.AddMinutes(60);

        SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy
        {
            Permissions = SharedAccessBlobPermissions.Read,
            SharedAccessStartTime = null,
            SharedAccessExpiryTime = new DateTimeOffset(toDateTime)
        };

        CloudBlockBlob blob = container.GetBlockBlobReference(blobName);
        string sas = blob.GetSharedAccessSignature(policy);

        return blob.Uri.AbsoluteUri + sas;
    }

This will iterate only 2 levels but not dynamically till the inner levels. I have blob in below hierarchy

  --Container
    --FolderA
      --FolderAA
        --FolderAA1
          --File1.txt
          --File2.txt              
        --FolderAA2
          --File1.txt
          --File2.txt
        --FolderAA3
     --FolderAB
       --File8.txt
     --FolderAC
       --File9.txt

This hierarchy is dynamic

Additional Question: Is there any GUI tool to copy blob data to target storage account?

kudlatiger
  • 3,028
  • 8
  • 48
  • 98

1 Answers1

1

UPDATE

According to your description, I modified it in the official sample code. It is already possible to completely copy the data in one container to another account, and the code has been uploaded to Github.

To use this sample code, you need to modify the App.Config file. Formal use to the production environment needs to be perfected.

https://github.com/Jason446620/BlobContainerCopy

enter image description here

PRIVIOUS

You can refer to the code in this post for copy operation. If the solution in this post does not help you, please let me know and I will continue to follow up to help you solve the problem.

And u can download Azure Storage Explorer is the GUI tool to copy datas.

enter image description here

Jason Pan
  • 15,263
  • 1
  • 14
  • 29
  • yes, the post you specified is my own question and followed the same solution. but unfortunately, an error now is in "copying" to destination. – kudlatiger May 18 '20 at 06:09
  • 1
    @kudlatiger I have try it success by myself. And I also put my demo code in Github. Your function is right, may be other functions error in your project. I use your function in offical sample code and it works, hope it useful to u. And if you run my code and also failed, maybe you need to `change access level` in your portal then try again. – Jason Pan May 18 '20 at 07:45
  • could u put source and destination storage in different Azure subscriptions? – kudlatiger May 18 '20 at 10:06
  • 1
    @kudlatiger Glad to help you.^-^ – Jason Pan May 19 '20 at 00:58