Sunday, November 9, 2025

Intro

Struggling to let users download a file from Azure Blob straight from a Canvas App? Been there. I tested a bunch of routes, hit the usual walls, and landed on a clean, one-liner Power Fx solution using only the Azure Blob Storage connector. Here’s the full story, what failed (and why), and the tiny formula that works reliably.

Solution

What you’ll build

A button in your Canvas App that generates a time‑limited link to a file in Azure Blob Storage and opens it so the browser downloads it.

The simple, robust approach (Power Fx only)

We let the connector create a share link (SAS) for the exact blob path, then we launch that URL so the browser handles the download.

Prereqs

  • Add the Azure Blob Storage connector (AzureBlobStorage) to your app.

  • Use a connection with permission to read the target container (typically via account key; follow your org’s policy).

  • Know your container/folder/file path.

TL;DR (the final formula)

TL;DR (the final formula)

Launch(AzureBlobStorage.CreateShareLinkByPath("AzureBlobContainer/Ynias/Download.xls").WebUrl)

With dynamic file selection + error handling

Set(
    linkRec,
    AzureBlobStorage.CreateShareLinkByPath(
        $"{txtContainer.Text}/{txtFolder.Text}/{galFiles.Selected.Name}"
    )
);

If(
    IsBlank(linkRec) || IsBlank(linkRec.WebUrl),
    Notify(
        "Could not generate download link. Please check the path and permissions.",
        NotificationType.Error
    ),
    Launch(linkRec.WebUrl)
);

Step-by-step setup (5 minutes)

  1. Connector: In your app, Add dataAzure Blob Storage.

  2. Connection: Provide account name/key (or your approved method).

  3. Path: Confirm your container and the blob path (e.g., invoices/2025/report.pdf).

  4. Button: Drop a Button → OnSelect = the one-liner above.

  5. Test: Play the app → click → file downloads.

What happens under the hood?

    • CreateShareLinkByPath() asks Azure to generate a short‑lived, permission‑scoped SAS link for that specific blob.

    • The returned record contains .WebUrl you can safely pass to Launch().

    • The browser navigates to this signed URL, Azure returns the file with proper headers, and the user gets the download prompt.

Common pitfalls & fixes

    • 403 or nothing happens
      Check that the path is correct and the connection has read permissions for that container.

    • Wrong file name in the browser
      Azure decides filename via blob name/headers. If you need a friendlier name, name the blob accordingly at upload time, or configure response headers when you generate the link (if your policy/process allows).

    • Link expired
      Share links are intentionally short‑lived. Just click again to generate a fresh link.

    • Multiple environments
      Ensure the connector is added and configured per environment and paths point to the right storage account/container for that environment.

Conclusion

Skip the hacks. A single Power Fx line with the Azure Blob connector gives you secure, time‑limited downloads without Power Automate, Base64 gymnastics, or public containers.

Why the obvious attempts failed

1) Download() with the direct blob URL

  • Symptom: Nothing downloads unless the blob is publicly accessible.

  • Why: Most production containers are private. Browsers need either anonymous access or a SAS token / auth header. Power Apps’ Download() can’t magically add Azure auth for you. A raw URL like https://account.blob.core.windows.net/container/file won’t work without a SAS.

2) Download() + AzureBlobStorage.GetFileContent()

  • Symptom: You can get the bytes, but getting the browser to treat them as a downloadable file is the problem.

  • Why: Download() expects a media value (or a direct, accessible URL). Handing it a raw blob/binary record from the connector doesn’t provide a browser-downloadable endpoint (content-disposition, filename, etc).

3) Power Automate → Base64 → Attachment control

  • Symptom: Overcomplicated, brittle, and not downloading.

  • Why: Attachment controls are designed for data sources that own attachments (SharePoint/Dataverse) and don’t support a simple “push Base64 in as default and download it” pattern. 

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.