John Livermore
John Livermore

Reputation: 31313

Azure blob, controlling filename on download

Our application enables users to upload files via a web browser. The file name gets mapped to a GUID and the blob name becomes the GUID. When the user clicks the file in our application it should download to their file system (show save as, etc) using the original file name and not the GUID blob name.

I found this post, and similar posts that describe how to set the Content-Disposition on the blob when downloading through a Shared Access Signature.

Friendly filename when public download Azure blob

However, our situation is a little different. We set a single SAS at the Container level (technically this is called a Shared Access Policy I believe -- you can have up to 5 at any given time). When downloading the blob, we simply append the SAS to the end of the uri, and use...

window.location.href = blobUri + containerSAS;

...to download the blob. This downloads the blob, but uses the GUID filename.

How can we take an existing SAS that applies to the Container and have the blob download as the original filename?

Keep in mind this is a slightly different use case from a SAS applied to an individual blob in that...

  1. The SAS is at the Container level (it seems this is the best practice vs. individual SAS's for each blob).
  2. We are downloading from javascript (vs. C# code where you can set the headers).

I have tried to set the Content-Disposition of the blob during the upload process (PUT operation), but it doesn't seem to make a difference when I download the blob. Below, you can see the Content-Disposition header being set for the PUT request (from Fiddler).

enter image description here

Thanks!

Upvotes: 4

Views: 3404

Answers (4)

nesterenes
nesterenes

Reputation: 232

Example for a read-only file available for 10-minutes only.

public string BuildSharedAccessPublicUrl(BlobClient blockBlob, string containerName, string filename)
{
    var sasBuilder = new BlobSasBuilder
    {
        BlobContainerName = containerName,
        Resource = "b",
        StartsOn = DateTimeOffset.UtcNow.AddMinutes(-5),
        ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(10),
        ContentDisposition = $"attachment; filename={filename}"
    };

    sasBuilder.SetPermissions(BlobSasPermissions.Read);
    var sasUri = blockBlob.GenerateSasUri(sasBuilder);

    return sasUri.AbsoluteUri;
}

Upvotes: 0

Chisskarzz
Chisskarzz

Reputation: 171

For anyone who still struggling, I made it work using the code snippet below in python. Just pass the content_disposition argument when generating the SAS. Thanks to @user3102567 answer

output_sas_blob = generate_blob_sas(
        account_name=storage_acct,
        container_name=storage_cont,
        blob_name=blobname,
        account_key=storage_key,
        permission=BlobSasPermissions(read=True, write=True, create=True),
        expiry=datetime.utcnow() + timedelta(hours=1),
        content_disposition=f"attachment; filename = {filename} "
    )

Upvotes: 0

user3102567
user3102567

Reputation: 133

This post pointed us in the right direction to change the file name with the the ContentDisposition property Azure.Storage.Blobs

            BlobContainerClient container = OpenContianer(containerName);
            BlobClient blob = container.GetBlobClient(sourceFilename);
            var Builder = new BlobSasBuilder(BlobSasPermissions.Read, DateTimeOffset.Now.AddMinutes(10));
            Builder.ContentDisposition= $"attachment; filename = {destFileName} ";
            var SasUri = blob.GenerateSasUri(Builder);

Upvotes: 6

John Livermore
John Livermore

Reputation: 31313

I have a solution. I think it's more of a workaround, but for each file to be downloaded, I make a server call and create a special SAS for the download operation. I can set Content-Disposition with that, and now the GUID named blobs are downloading with their original filenames.

Upvotes: 1

Related Questions