Mapping Of File Attribute From One Entity To Another Through Plugin

Introduction

File Type column is introduced by Microsoft for Dataverse Model-Driven and canvas app. When you add File Type column on Model-Driven Entity form, it will be enabled once you save your record. More details about File Type column can be found here.

In today's blog, I will show you how we can map file type column from parent entity to child entity through Plugin. OOB relationship field mapping does not give you the option to Map File type column so to achieve this requirement we will have to write plugin code.

Parent Entity -> Employee [File Column added]
Child Entity -> Building [File Column added]

The requirement is when we add Building entity record from Employee Associated grid, File column should be automatically mapped -

Sample Code to download the file from Employee Entity,

// Download file
var initializeFile = new InitializeFileBlocksDownloadRequest {
    FileAttributeName = "cr127_filecolumn",
        Target = employee.ToEntityReference()
};
var fileResponse = (InitializeFileBlocksDownloadResponse) service.Execute(initializeFile);
var req = new DownloadBlockRequest {
    FileContinuationToken = fileResponse.FileContinuationToken, BlockLength = fileResponse.FileSizeInBytes
};
var response = (DownloadBlockResponse) service.Execute(req);

As you can see we need to provide File attribute schema name from Employee Entity and Record entity reference to download the file. Now once file is downloaded we need to upload the file to Building Entity.

Sample code to upload the file to Building Entity file column,

// Upload file
var limit = 4194304;
var blockIds = new List < string > ();
var initializeFileUploadRequest = new InitializeFileBlocksUploadRequest {
    FileAttributeName = "cr127_filecolumn",
        Target = entity.ToEntityReference(),
        FileName = fileResponse.FileName
};
var fileUploadResponse = (InitializeFileBlocksUploadResponse) service.Execute(initializeFileUploadRequest);
for (int i = 0; i < Math.Ceiling(response.Data.Length / Convert.ToDecimal(limit)); i++) {
    var blockId = Convert.ToBase64String(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()));
    blockIds.Add(blockId);
    var blockData = response.Data.Skip(i * limit).Take(limit).ToArray();
    var blockRequest = new UploadBlockRequest() {
        FileContinuationToken = fileUploadResponse.FileContinuationToken, BlockId = blockId, BlockData = blockData
    };
    var blockResponse = (UploadBlockResponse) service.Execute(blockRequest);
}
var commitRequest = new CommitFileBlocksUploadRequest() {
    BlockList = blockIds.ToArray(),
        FileContinuationToken = fileUploadResponse.FileContinuationToken,
        FileName = fileResponse.FileName,
        MimeType = GetMimeType(fileResponse.FileName),
};
service.Execute(commitRequest);

To upload the file to Building entity we need to provide file column schema name from Building Entity and Building entity record reference. Other file details can be passed from Download file request like File content, Mime Type, FileName etc.

Complete plugin code can be downloaded from my github repo here.

Once plugin code is deployed/Registered, create new plugin step on Child Entity, Create message and Post operation Async.

Mapping Of File Attribute From One Entity To Another Through Plugin

Final Result

Mapping Of File Attribute From One Entity To Another Through Plugin

Mapping Of File Attribute From One Entity To Another Through Plugin

Note

  1. The step is registered as async because when I registered the step on sync it was not working. I think it was not working because File field will be enabled only when you first save the record meaning record should be an existing record.
  2. End user has to refresh their form to see the file column value populated because step is async.

Hope this helps!