Power Apps: Download File From Dataverse File Column

Power Apps: Download File From Dataverse File Column

You can create a button in Power Apps to download a file stored in a Dataverse file column. To do this, you must use the Dataverse Web API. If you haven’t used the Web API before it might be a little bit confusing. In this article I will show you how to use the Dataverse Web API in Power Apps to download a file from a file column.

Table of Contents
• Introduction: The Download File ButtonCreate The Dataverse Table With A File ColumnAdd A Download Button To A Canvas AppConstruct A Dataverse Web API Request To Get A FileStore The Environment URL In An Environment VariableReference The Environment Variable In A Canvas App




Introduction: The Download File Button

A Power Platform developer is making an app to give Project Managers access to Vendor Invoices. When a Project Manager selects the Download File button the file is downloaded from Dataverse to their device.




Create The Dataverse Table With A File Column

Setup a new Dataverse table named Vendor Invoices. Include the following columns and file types.

  • Name (text)
  • Invoice File (file type)



Add a new record to the table and store a PDF file in the Invoice File column.



This example uses a sample invoice from the AI Builder Lab but we can use any valid PDF.




Add A Download Button To A Canvas App

When a user selects the Download File button in a canvas app the file is downloaded to their device. To do this, we must construct a URL to make a request to GET the file using the Dataverse Web API. The example below uses a URL built to get the PDF file we uploaded earlier. I will show you the required structure of the URL first and then show you how to get the pieces to build your own.

Open Power Apps Studio and create a new app from blank. Insert a button onto the screen.



Use this code in the OnSelect property of the button to download the file. The URL retrieves a table row using the Web API for the Vendor Invoice record with the unique identifier 23b9bbbe-0bee-ee11-a1fd-000d3af40608 and gets the Invoice File. I will show you how to build your own URL in the next section of this tutorial.

Download($"https://org81a4e3c2.crm3.dynamics.com/api/data/v9.2/md_vendorinvoices(23b9bbbe-0bee-ee11-a1fd-000d3af40608)/md_invoicefile/$value"
)



Test the button in Power Apps to ensure it works.




Construct A Dataverse Web API Request To Get A File

To build your own URL you will need to use this structure and supply your own environment url, table name, record id and column name. We will get this information by using the Dataverse Web API.

https://<environment_url>/api/data/v9.2/<table_name>(<record_id>)/<column_name>/$value



Get the environment url from the the Power Platform admin center.



Find the table name by navigating to https://<environment url>/api/data/v9.2 in your web browser and inspecting the JSON output.



Then use the Web API to get a list of all the invoice file records using the URL https://<environment_url>/api/data/v9.2/<table_name>. Then get the record id of the record the file is found within.



Finally, get the column name using the URL https://<environment_url>/api/data/v9.2/<table_name>(<record_id>).




Store The Environment URL In An Environment Variable

Hardcoding the environment URL is not a good idea because it will remain the same when moving the app from the development environment to the production environment. We should reference an environment variable which holds the environment URL in our code instead.

Create a new environment variable inside of a solution.



Make the display name Environment URL. Choose the data type Text. Then write the environment url for in the Current Value field.




Reference The Environment Variable In A Canvas App

To use the new environment variable in the canvas app connect it to the following two data tables:

  • Environment Variable Defintions
  • Environment Variable Values



Then replace the OnSelect property code of the download file button with this code instead. It performs a lookup on the environment variable values table and gets the environment variable with the matching display name.

Download(
    $"{LookUp(
        'Environment Variable Values',
        'Environment Variable Definition'.'Display Name' = "Environment URL",
        Value
    )}/api/data/v9.2/md_vendorinvoices(23b9bbbe-0bee-ee11-a1fd-000d3af40608)/md_invoicefile/$value"
)



The download file button still works exactly the same as before but now the app can be moved to a different environment and point to a different database.




Questions?

If you have any questions or feedback about Power Apps: Download File From Dataverse File Column please leave a message in the comments section below. You can post using your email address and are not required to create an account to join the discussion.

Matthew Devaney

Subscribe
Notify of
guest

33 Comments
Oldest
Newest
Inline Feedbacks
View all comments
Bogdan
Bogdan
6 months ago

Have you ran into any bugs with downloading the file type Dataverse column in a canvas app? I ran into a bug where the Dynamics 365 cookie for authentication was missing giving me an error when downloading the file from the API. The fix was to launch the environment base URL to obtain that cookie, then use the API for the file like in your article.

Yoahi
Yoahi
6 months ago
Reply to  Bogdan

This is by design. Matt’s process works fine as long as you have the cookie cached. Canvas Apps cannot provide a cookie for the request as it will be rejected due to CORS.

Raj
Raj
6 months ago

Can we make it much more dynamic like the dataverse table can be assigned as variable and the guid value can be assigned as variable

Fadi
Fadi
6 months ago

Thank you, Matthew. I wish that could be done the same for the SharePoint list or library

Babak
Babak
6 months ago

Hi Matthew,

I had implemented this solution in app before. But, the problem I faced was that the user should have logged in “organization.crm3.dynamics.com”. Otherwise, he would receive a 401 error. Have you had any similar experience?

ManishM
ManishM
6 months ago

I am having this problem. the users are part of a security role in the environment but they still are getting the 401 error.

ManishM
ManishM
6 months ago

Hello Matthew, I have tried this method several times including creating Environment Variable (how you have demo-ed here), the download works great for me as the system admin and app maker, but it fails for my users giving “HTTP ERROR 401”. I searched for the error; it is related to authorization. My test users have full CRUD access to the table and they can do all operations in that table.

I cannot tell what I am missing and which checkbox I need to check in the environment. Any guidance would really help. Thank you, Manish.

ManishM
ManishM
6 months ago
Reply to  ManishM

Hi Matthew (or anyone knowing what I may be doing wrong), any insight into this would really help. My app has lot of files for users to download and currently I do not have any efficient way to download group of files in one click. thank you for your kind attention.

Nas
Nas
6 months ago
Reply to  ManishM

Hi All,
I am also facing this same issue. Users are getting http error 401.

Incidentally, it was working for me as the app/table creator, but not for other users.
However just today it is not working for me either?!

Thanks!

BTW: Great article as always Mathew.

Justin L
Justin L
6 months ago
Reply to  ManishM

Hi ManishM,

Check out some of the other comments on this 401 error. Your users must visit the base URL and authenticate there if not automatically signed in. I have run into this issue myself. The users hate it, but I haven’t found the magic permissions to fix this. I have considered adding a little help icon or link for users to click on if they run into this 401 error. I would just route them to the base URL in a new tab and advise them to sign in there, then come back and resume their attempt to download the files.

ManishM
ManishM
6 months ago
Reply to  Justin L

Thank you for the guidance. I am a little unclear as to what is base URL that the users should visit and sign-in before they are able to download the files. Please guide me based on how you managed to work this graceful UX… thank you.

ManishM
ManishM
6 months ago
Reply to  Justin L

Hi Justin L, I was able to find the base URL and test it with one of my test users. It worked like a charm! Now, the visit to the base URL is nowhere graceful interaction for my users. Are there techniques to do this better or stealthily because the base URL did not ask the test users for any sign-in? The landing page said that the user does not have permission – basically negative sentiment.

thank you so much 🙂

Justin Lynch
Justin Lynch
6 months ago
Reply to  ManishM

I share your sentiment. Not that I have found unfortunately. I am considering adding a link to the screen where the download is initiated saying something like “Issue with 401 error? Click and sign in here.” which would launch the base url that the user needs to visit and authenticate with so that the downloads work.

Nuno
Nuno
6 months ago

Matthew,
I’m trying to download an Excel file from Dataverse, following the instructions on this post, but I’m getting the error:
{
  “error”: {
    “code”: “0x80060888”,
    “message”: “Resource not found for the segment ‘cre05_exportacoesficheiroes’.”
  }
}

Sonofbob
Sonofbob
6 months ago
Reply to  Nuno

I faced this issue too and realised I had put my table name in the singular form rather than the plural form. Are you certain you have the correct plural form for your table?

Barry
Barry
5 months ago

Hi,
Since this is causing 401 errors for users, is there another method for downloading files from Dataverse?

Barry
Barry
5 months ago

The client would not agree. Looking for something more seamless

Mohammad
Mohammad
2 months ago

Hi Matthew,

When I download a file using the Attachment control, it generates a blob storage link with a one-hour expiration token. I was wondering if this solution works the same way.
In my use case, I need to ensure that the file is downloaded directly and securely from Dataverse, and no additional download link (containing a signature/token) is created.

Kiruthika
Kiruthika
9 days ago

Hi Matthew, Thanks! for this solution, always your posts are inspiring. I face the same issue…I am able to download, but other users get 401 error. Is there a solution for that ?

priya
priya
5 months ago

Hi mathew when am clicking on download button it is showing URL passed to the function is not valid

Dave
Dave
4 months ago
Reply to  priya

Make sure you have https:// at the start of your URL

Nuno
3 months ago

I’ve finally made it!
Not having the environment URL as an environment variable was not working for me.
I have no idea why, since the whole URL is exactly the same.
Thanks for this excellent content!

Last edited 3 months ago by Nuno
Mark
Mark
3 months ago

How would I go about inserting this into a download function for a gallery? I’ve been trying to replace the ID portion with something more dynamic (ThisItem. type of function) but can’t get anything to work. Any possible soultions?

Mert Adsay
Mert Adsay
3 months ago

Hello Matthew, how can we download the files when offline mode enabled? Is there a specific uri for that?

Dave Jacskon
Dave Jacskon
3 months ago

This works great. Now that I have files in Dataverse which i can download, can we rename them from within our canvas powerapp?

Tina
Tina
3 months ago

Thanks for the tips, Matthew. Super helpful!
Also, it there a way to change the downloaded image file type and metadata?

  1. If i upload a jpg image file, the downloaded file type is always .jfif.
  2. When right click to save the image, is it possible to pre-configured the image file name so it’s not a random name like download (5).jfif?
Daniel Hall
Daniel Hall
3 months ago

I’m trying this method with an image column and end up with an empty file named “$value”. The image column data in json is a huge block of (seemingly) random characters. If I use the “/Image/download.aspx?” url it opens in a new tab. I’m wondering I’m missing a step

sunny
sunny
19 days ago

For me its working with table set name