Search code examples
c#azure-storageazure-blob-storage

Copy blob between storage accounts


I'm trying to copy a blob from one storage account to another (In a different location).

I'm using the following code:

var sourceContainer = sourceClient.GetContainerReference(containerId);
var sourceBlob = sourceContainer.GetBlockBlobReference(blobId);
if (await sourceBlob.ExistsAsync().ConfigureAwait(false))
{
    var targetContainer = targetClient.GetContainerReference(containerId);
    await targetContainer.CreateIfNotExistsAsync().ConfigureAwait(false);
    var targetBlob = targetContainer.GetBlockBlobReference(blobId);
    await targetBlob.DeleteIfExistsAsync().ConfigureAwait(false);
    await targetBlob.StartCopyAsync(sourceBlob).ConfigureAwait(false);
}

and I get a "Not Found" error. I do get that the source blob indeed exists. Am I using the wrong command? Is there something I'm missing regarding copying between storage accounts?


Solution

  • After playing around with the code, I reached an answer. Copying between storage accounts can only be achieved when the source blob is a uri and not a blob reference. The following code worked:

    var sourceContainer = sourceClient.GetContainerReference(containerId);
    var sourceBlob = sourceContainer.GetBlockBlobReference(blobId);
    // Create a policy for reading the blob.
    var policy = new SharedAccessBlobPolicy
    {
        Permissions = SharedAccessBlobPermissions.Read,
        SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-15),
        SharedAccessExpiryTime = DateTime.UtcNow.AddDays(7)
    };
    // Get SAS of that policy.
    var sourceBlobToken = sourceBlob.GetSharedAccessSignature(policy);
    // Make a full uri with the sas for the blob.
    var sourceBlobSAS = string.Format("{0}{1}", sourceBlob.Uri, sourceBlobToken);
    var targetContainer = targetClient.GetContainerReference(containerId);
    await targetContainer.CreateIfNotExistsAsync().ConfigureAwait(false);
    var targetBlob = targetContainer.GetBlockBlobReference(blobId);
    await targetBlob.DeleteIfExistsAsync().ConfigureAwait(false);
    await targetBlob.StartCopyAsync(new Uri(sourceBlobSAS)).ConfigureAwait(false);
    

    Hope it will help someone in the future.