Handle Base64 and Binary File Content Types in Power Automate

Did you know that there are two types of file or image content type used in the input and output parameters? In this post, you will learn how to handle the different types of file content in the cloud flow action parameters.


When working with the input and output parameters for file content, you need to provide a value as Binary data type for most of the input parameters (e.g. Upload file or image content) and its counterpart action (e.g. Get file or image content) returns the value in Binary data type. However, some of the actions require the Base64 data type and some outputs return Base64 data type. So how do you identify what you need and when to convert which?

Understanding what type of file content to use in certain parameter is important. Sometimes, conversion of one type to another is required when the type of the output is different from the required input for the next step (e.g. get the Note attachment file and upload to SharePoint).

Identification

To identify the file content type of the input/output parameters, the Connectors Documentation is the best place to start.

However, Microsoft Docs will not cover everything and you will need to figure out some dynamic parameters like documentbody value of the Note table or image column value by running the flow first to see the output value that is available for you to use.

One of the readers, DerekHotguns, suggested one good checking point for content formats which is the Content-Type header on API response. If the header is "application/octet-stream" then it's binary, else base64. (there could be some other exceptions but that is the case for most of the API responses).

🔗 Binary

All of the actions in the SharePoint connectors are consistent. Create file action requires the file content in Binary data type to upload the file and Get file content or Get file content using path returns the Binary data type. In Microsoft Dataverse connector, Upload file or image content and Get file or image content uses the Binary data type but the rest of the parameters seems to be Base64.

🔗 Base64

To create a Note attachment, Base64 data type value needs to be populated in the Document column and Base64 value is returned when the documentbody column is retrieved from the Note table.

The same applies to retrieving the image column which returns the Base64 value.

To use images in the Populate a Microsoft Word template action, the file content value needs to be constructed with the Compose action with Base64 value in the following format, unless the value is already a binary value of JPG or PNG.
{ "$content-type": "image/png", "$content": "iVBORw0KG...i/DhQmCC" }
You can read more details on this topic from Olena Grischenko's blog post about Populating Word template with the image field content from Microsoft Dataverse.

Conversion

To convert from Base64 to Binary data type, there is a base64ToBinary function. However, there is no such function for converting the other way round. The trick to converting the other way around is to set the Binary value into the Compose action and use the ['$content'] property of the output. You can also directly use the ['$content'] property of the Binary output too (e.g. outputs('Get_file_or_image_content')?['body/$content'] will return Base64 value). You can find more details about Binary to Base64 conversion in the blog post .

Now let's see the conversions in action.

🔗 Create Note Attachment from SharePoint File

Get file content action will return the SharePoint file content in Binary but creating a Note attachment requires Base64 value. Using the ['$content'] property of the output with the following expression will populate with Base64 value to the Document column.
outputs('Get_file_content')?['body']?['$content']

🔗 Upload File with Binary Data

To upload the Binary data (e.g. documentbody column value of the Note attachment) to SharePoint or File data type column, base64ToBinary function can be used.
base64ToBinary(outputs('Get_a_Note_Attachment')?['body/documentbody'])

Populate Word Template Image

To construct the file content for the image placeholder in the Word template with the Binary data type, ['$content'] property can be used as in the following expression.
outputs('Get_file_or_image_content')?['body/$content']

🛈 Note

Compose action step is required to construct the input for the image content using the Base64 value and populate the output of the Compose step to the image placeholder. If the content JSON is directly populated, the step will fail with the following error.
The image is not of type PNG or JPG. Please provide an image of type PNG or JPG.

Summary

There are two types of file content (Binary and Base64) used in the input and output parameters and it is important to use the correct type based on the required parameter. To convert from Base64 to Binary, base64ToBinary function can be used and ['$content'] property of the Binary output can be used when needing a Base64 value.

Comments

  1. This is so helpful! Thank you so much for putting all of the information together and clearing the confusion when working with file content in power automate.

    ReplyDelete
  2. Hi,
    We have been using this expression base64ToBinary() to create a note related case, when portal comment is added from dynamics portal.
    From yesterday the flow has started failing on the conversion step, due the mentioned flow error.

    Message for Error:
    {
    "error": {
    "code": "0x80040278",
    "message": "Invalid character in field 'documentbody': '.', hexadecimal value 0x00, is an invalid character.",
    "@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionSourceKey": "Plugin/Microsoft.Crm.ObjectModel.AnnotationService",
    "@Microsoft.PowerApps.CDS.ErrorDetails.ApiStepKey": "753b8615-ecd8-db11-b397-0019b9204da9",
    "@Microsoft.PowerApps.CDS.ErrorDetails.ApiDepthKey": "1",
    "@Microsoft.PowerApps.CDS.ErrorDetails.ApiActivityIdKey": "5eacdd4f-8dbc-4add-9ec0-47ea1ef0da17",
    "@Microsoft.PowerApps.CDS.ErrorDetails.ApiPluginSolutionNameKey": "System",
    "@Microsoft.PowerApps.CDS.ErrorDetails.ApiStepSolutionNameKey": "System",
    "@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionCategory": "ClientError",
    "@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionMesageName": "InvalidCharactersInField",
    "@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionHttpStatusCode": "400",
    "@Microsoft.PowerApps.CDS.HelpLink": "http://go.microsoft.com/fwlink/?LinkID=398563&error=Microsoft.Crm.CrmException%3a80040278&client=platform",
    "@Microsoft.PowerApps.CDS.InnerError.Message": "Invalid character in field 'documentbody': '.', hexadecimal value 0x00, is an invalid character."
    }
    }


    Any idea why this is happening? Nothing has been changed from our end.

    ReplyDelete
    Replies
    1. I am not sure how it was working previously but as mentioned in my example below, you will need to provide Base64 value to create a Note attachment. If you are using the expression base64ToBinary(), the input value becomes binary and thus, it is failing with that error.

      https://linnzawwin.blogspot.com/2021/02/handle-base64-and-binary-file-content.html#binary-to-base64

      Delete
  3. If you want to get a multiple files contents, (.xls,.csv,.txt,.jpg) and send them in one email, which expression should be use to to fit all of them

    ReplyDelete
    Replies
    1. You will have to create multiple Attachment (ActivityMimeAttachment) rows with those file content as mentioned in the step 5 of this blog post.

      https://linnzawwin.blogspot.com/2020/05/send-email-from-dynamics-365cds-with.html#CreateAttachment

      Delete
  4. Is there a way to custom populate the Library Name? We have the same flow across multiple sites, and I was trying to build a variable to populate the Library Name, but it looks like the flow is expecting a GUID for Library Name.

    ReplyDelete
  5. I'm trying different ways to make it works without success.

    From what I understand from your post is that the word template should accept the format ("binary") returned by Power automate download File Action. Here my variable (this example is using a png file but I tried Jpeg as well).

    {
    "inputs": {
    "name": "signature",
    "value": "{\n\"$content-type\":\"image/png\",\n\"$content\":\"@{body('Télécharger_un_fichier_ou_une_image')['$content']}\"\n}"
    },
    "metadata": {
    "operationMetadataId": "a95e30cc-1dd3-40a0-a04e-aeeb1abacac5"
    }
    }

    ReplyDelete
    Replies
    1. I a still having a bad request error on word document generation

      Delete
    2. error detail : The image is not of type PNG or JPG. Please provide an image of type PNG or JPG.\r\nclientRequestId: 79bb026c-0e30-4d1c-8262-0d8920b1bb2f

      Delete
    3. Populate a Microsoft Word template action was listed under the Base64 section of my blog. It only accepts the base64 format, so you will need to apply base64(…) function returned by your Power Automate download File Action.

      You can try to add it in the Compose step
      https://msolenacrm.files.wordpress.com/2020/09/image-18.png

      and see if the output of the compose step looks something like this.
      https://msolenacrm.files.wordpress.com/2020/05/image-14.png

      Check out Olena's blog post for more details.
      https://msolenacrm.blog/2020/05/12/populating-word-template-with-the-cds-image-field-content-via-flow-power-automate/

      Delete
  6. Hi Linn, I'm trying to convert the Base64 file as a Binary file in SharePoint using Power Automate. But when I use the Base64toBinary function to get the Binary value of the File content, it gives the same Base64 values from my Base64 file. Is there any other way I can convert the Base64 file content value to Binary ?

    ReplyDelete
    Replies
    1. @Ganapathy
      When you use base64toBinary function to get the Binary value of the File content, it still shows the Base64 values in the flow designer as part of the output value but it is a bit different.

      https://www.screencast.com/t/EbIqRrYXU
      If you look at the screenshot above, the first Compose action contains the Base64 data. The second Compose action is the binary data after converting with the base64toBinary function (which has shown as a JSON object with $content-type even though the value of the $content is still Base64).
      However, you can use that value to create a SharePoint "Create File" action File Content, it will just work.

      Delete
    2. Hello Linn, Thanks for your response. I have tried in the same way but I still get the file content as Base64 value.

      In my 1st Compose, I get the "File Content" ( and in the 2nd Compose, I used the base64toBinary Function "base64ToBinary(outputs('Get_file_content')?['body'])" , as you said it still shows as Base64 value.

      My file Content is like this "IDQgMCBSL0dyb3VwPDwvVHlwZS9Hcm91cC9TL1RyYW5zcGFyZW5jeS9DUy9EZXZpY" and I'm trying to convert the file content as Binary like "01100101 01101110 01100100 01101111 01100010 01101010"

      Please correct me if my flow or the function used wrongly.

      https://app.screencast.com/collections/g000300tJtSY9mm2flXH3uq9zMfTY

      Delete
    3. @Ganapathy
      The output of the "base64ToBinary(outputs('Get_file_content')?['body'])" is indeed binary data. It is just that the flow run history would show it as a JSON wih $content.

      I don't see any issue with your flow and after your "Create file" action created a file in SharePoint, are you able to download and open the "BinaryTest.txt file and see the content?

      Delete
    4. Yes Linn, I can see the BinaryText.txt file created in my SharePoint but when I open the file, I still see the same Base64 Content not the Binary Content.

      Delete
    5. Have you tried opening it in Notepad and see the proper text? If that's the case we can say that your file was property created in SharePoint with correct content.

      In your next flow to Get File Content, the output of the action maybe in Base64 and that's depending on the content type of the action. No matter how you create the file, that content type will be in the same format. If you need the binary content there, you'll have to convert the Base64 to binary in that flow.

      Delete
    6. Yes Linn, I opened the Notepad and checked. This time the Output file "BinaryText.txt" contain a String value instead of Binary. So I need to use the Base64toBinary function in the Create File Action in order to get the Binary content in the file?

      https://app.screencast.com/JRjNqd3acOMj1 - Flow
      https://app.screencast.com/NItQmGajO14ur - Output File Content

      Delete
    7. Yes, that depends on the format of the source data. If the source data is Base64, you need to use Base64toBinary function.

      What is the source data of the content? If it is from the "Get file content" of SharePoint connector, you can just use without converting to binary.

      My test flow in designer mode - https://www.screencast.com/t/ZaBnZsMBJ4
      Flow Run Result - https://www.screencast.com/t/aAtOcltFK5
      Preview of uploaded file to SharePoint - https://www.screencast.com/t/kGjwD5qp62SU

      Another flow Create File using the content from Get file content without conversion - https://www.screencast.com/t/Do6CjHWKqs

      Delete
    8. Thank you! Linn. I realized that we cannot get the Binary Content even if we use the Base64toBinary Function after the Get File Content or in the File Creation step. If I'm not wrong the conversation function gives the JSON representation of Binary Output.

      https://app.screencast.com/rR4YKox2BhM2D

      Delete
    9. Yes, that's what I was trying to explain the first place about "shown as a JSON object with $content-type" which is the JSON representation of Binary Output.
      At least glad to know that your mystery is solved.

      Delete
  7. I am attempting to access this data via PowerShell. It would seem doing the Base64 to Binary conversion may need an encoding type. Do you know what encoding type the Base64toBinary() function is using?

    ReplyDelete
    Replies
    1. Sorry, I don't know about that either. I just checked the MS Learn page about it and it doesn't specify anything about it either.

      https://learn.microsoft.com/azure/logic-apps/workflow-definition-language-functions-reference?WT.mc_id=DX-MVP-5003873#base64tobinary

      Delete
  8. Thank you, this was a superb. I started my Power automate journey at this week, and now I could get documents from external system and insert them to Notes table with correct format.
    One good checking point for content formats is Content-Type header on API response. If header is "application/octet stream" then it's binary, else base64. Yes, there could be a some other variations, but mainly so.

    ReplyDelete
    Replies
    1. Thanks for your tips and sharing with us. I'll add it to my post.

      Delete
  9. My experience with Encodian-to-Microsoft actions were a bit different. I am using the Encodian "Convert HTML to PDF" action, and using the Outlook365 "Send an email (V2)" action to send the file contents generated by the "Convert HTML to PDF" action as an email attachment. In order for it to work, I had to configure the attachment file content like this:

    [
    {
    "Name": @{outputs('Convert_HTML_to_PDF')?['body/Filename']},
    "ContentBytes": {
    "$content-type": "application/pdf",
    "$content": "@{base64toString(base64(outputs('Convert_HTML_to_PDF')?['body']?['FileContent']))}"
    }
    }
    ]

    Yes, I had to explicitly use the base64() function to convert the file contents coming from Encodian to base64. Then, I convert to a string using base64toString() to decode back to a string. I'm not sure why it needs to be this way, but it does work.

    ReplyDelete
    Replies
    1. I was also struggling with this until I used the the base64() function. Thanks Tom for the heads up.

      Delete
    2. Thank you all for sharing your experience/observation with the other readers. 😊

      Delete
  10. The example for CloseIncident saved my day. Fantastic! Many thanks.

    ReplyDelete
  11. Hello, I am trying to write a flow to upload a large file by chunk and upload method to SharePoint, reason for chunking is to avoid the action level limits of the flow (50 MB from Dataverse and 100 MB in HTTP Actions) - I have tried to use both Microsoft Graph approach and the basic SharePoint Approach using "Send an HTTP request to SharePoint" action. Now, I know it works from python and C# by first creating an empty file and then using the uniqueId in the following startUpload, continueUpload requests. And I want to use the SharePoint approach rather than Microsoft Graph due to security permissions requirements, which Graph needs a lot of. But, I think there is a very basic issue I am getting stuck at, I supply base64 chunks to the flow, and if I simply keep uploading and appending the base64 payload - it doesn't convert it to binary like it does in case of Azure Blob Storage, and if I convert it to binary and use fileoffset, still each chunk gets uploaded with the wrong size and finally don't work. I have tried the simplest form when the file size is less than the chunk size, and then the flow simply creates the file. But even then, I see the same problem - so, there is something very basic I am missing here, because I am not using Create File Action, as I cannot use it obviously. What is it that I am missing ? Please help.

    ReplyDelete
    Replies
    1. How did you pass through the file content in the "Send an HTTP request to SharePoint" action?

      The Body parameter only accept the request content in JSON, so you might have to format the JSON properties properly for your the startUpload, continueUpload, and finishUpload requests.

      My suggestion is to make those SharePoint API Calls With Postman and figure out the correct syntax for the JSON and then, apply the same in the flow.
      https://www.penthara.com/quickly-work-with-sharepoint-api-calls-with-postman/

      Delete

Post a Comment