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 Button
• Create The Dataverse Table With A File Column
• Add A Download Button To A Canvas App
• Construct A Dataverse Web API Request To Get A File
• Store The Environment URL In An Environment Variable
• Reference 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.
Did You Enjoy This Article? 😺
Subscribe to get new Power Apps & Power Automate articles sent to your inbox each week for FREE
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.
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.
Bogdan,
Can’t say I’ve run into bugs. But I do wonder why this isn’t easier. Working in Dataverse is supposed to be the best fit for Power Apps. So we shouldn’t have to resort to hacky workarounds that are not solution-aware like this trick.
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.
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
Raj,
Yes you can make it dynamic as you like.
Thank you, Matthew. I wish that could be done the same for the SharePoint list or library
Fadi,
I already wrote how to download a file from SharePoint libraries. Thankfully, it is much easier than Dataverse. Search my blog for it.
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?
Babak,
The user is already be logged in when they started to use the app so it wouldn’t appear to be a problem.
I am having this problem. the users are part of a security role in the environment but they still are getting the 401 error.
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.
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.
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.
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.
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.
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 🙂
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.
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’.”
}
}
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?
Hi,
Since this is causing 401 errors for users, is there another method for downloading files from Dataverse?
Barry,
You could have a user click on the attachments control. Maybe you could even make it invisible and place it over top of a button!
The client would not agree. Looking for something more seamless
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.
Hi mathew when am clicking on download button it is showing URL passed to the function is not valid
Make sure you have https:// at the start of your URL
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!
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?
Hello Matthew, how can we download the files when offline mode enabled? Is there a specific uri for that?
This works great. Now that I have files in Dataverse which i can download, can we rename them from within our canvas powerapp?
Thanks for the tips, Matthew. Super helpful!
Also, it there a way to change the downloaded image file type and metadata?
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