Understanding MIME Types in Power Platform – Quick Review

While many people doesn’t know the significance of MIME Type, this post is to give brief knowledge about the same before moving to understand security concepts in Power Platform in my upcoming articles.

In the Microsoft Power Platform, MIME types (Multipurpose Internet Mail Extensions) are standardized labels used to identify the format of data files. They are critical for ensuring that applications like Power Apps, Power Automate, and Power Pages can correctly process, display, or transmit files. 

Core Functions in Power Platform

  • Dataverse Storage: Tables such as ActivityMimeAttachment and Annotation (Notes) use a dedicated MimeType column to store the format of attached files alongside their Base64-encoded content.
  • Security & Governance: Administrators can use the Power Platform Admin Center to block specific “dangerous” MIME types (e.g., executables) from being uploaded as attachments to protect the environment.
  • Power Automate Approvals: You can configure approval flows to fail if they contain blocked file types, providing an extra layer of security for email notifications.
  • Power Pages (Web Templates): When creating custom web templates, the MIME type field controls how the server responds to a browser. For example, templates generating JSON must be set to application/json to be parsed correctly.
  • Email Operations: When using connectors like Office 365 Outlook, you must specify the MIME type for attachments (e.g., application/pdf for PDFs) so the recipient’s client can open them properly. 

Common MIME Types Used

File Extension MIME Type
.pdfapplication/pdf
.docxapplication/vnd.openxmlformats-officedocument.wordprocessingml.document
.xlsxapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet
.png / .jpgimage/png / image/jpeg
.jsonapplication/json
Unknownapplication/octet-stream (used for generic binary files)

Implementing MIME type handling and file restrictions ensures your Power Platform solutions are both functional and secure.

1. Programmatically Setting MIME Types in Power Automate 

When working with file content in Power Automate, you often need to define the MIME type within a JSON object so connectors (like Outlook or HTTP) understand how to process the data. 

  • Structure: Use a Compose action to build a file object with the $content-type (MIME type) and $content (Base64 data).json
  • Dynamic Mapping: If you don’t know the file type in advance, you can use an expression to map extensions to MIME types or use connectors like Cloudmersive to automatically detect document type information. 

2. Restricting File Types in Power Apps

The Attachment control in Power Apps does not have a built-in “allowed types” property, so you must use Power Fx formulas to validate files after they are added. 

  • Validation on Add: Use the OnAddFile property of the attachment control to check the extension and notify the user if it’s invalid in PowerApps
  • Submit Button Logic: For added security, set the DisplayMode of your Submit button to Disabled if any attachment in the list doesn’t match your criteria. 

3. Global Restrictions (Admin Center)

To enforce security across the entire environment, administrators can navigate to the Power Platform Admin Center to manage blocked MIME types. Adding an extension to the blocked file extensions list prevents users from uploading those file types to Dataverse tables like Notes or email attachments. 

Hope this helps…in next post, I will be talking about Content Security Policy and how Power Platform can be secured using different sets of configuration.

Cheers,

PMDY

🔄Power Platform Environment Restore: Options & Best Practices

Hi Folks,

Restoring environments in Power Platform has evolved significantly.

In the past, Dynamics CRM On-Premise users relied on SQL database backups and manual restores. Today, administrators can perform environment restores in online instances with just a few clicks via the Power Platform Admin Center.

This guide outlines the available restore options and key considerations to ensure a smooth and secure process.

🛠️ Restore Options in Power Platform

OptionDescription
1. Manual Backup RestoreRestore from a backup you manually created. Ideal before major customizations or version updates.
2. System Backup RestoreUse automated system backups created by Microsoft. Convenient but less flexible than manual backups.
3. Full CopyClone the entire environment, including data, customizations, and configurations. Suitable for staging or testing.
4. Partial Copy (Customizations & Schema Only)Copies only solutions and schema—no data. Best for promoting configurations from Production to SIT/UAT.

✅ Best Practices & Key Considerations

  • Use Partial Copy for Non-Production: When restoring from Production to SIT/UAT, prefer Partial Copy to avoid data and configuration mismatches. This brings all solutions without the underlying data.
  • Use Full Copy: In case it is restoring to a same type of environment
  • Avoid Restoring Production Backups to Non-Prod: Manual or system backups from Production should not be restored to non-production environments. This often leads to configuration conflicts and user access issues.
  • Update Security Groups: Always update the Security Group when restoring or copying to a different environment type. Otherwise, users may be unable to log in due to mismatched access controls.
  • Manual Backup Timing: After creating a manual backup, wait 10–15 minutes before initiating a restore. This ensures the backup is fully processed and available.
  • Regional Restore Limitation: You can only restore an environment to another environment within the same region.
  • Unlimited Manual Backups: There’s no cap on the number of manual backups you can create—use this flexibility to safeguard key milestones.
  • Exclude Audit Logs When Possible: Including Audit Logs in copies or restores can significantly increase processing time. Exclude them unless absolutely necessary.

🧠 Technical Note

All backup and restore operations in Power Platform are powered by SQL-based technology under the hood, ensuring consistency and reliability across environments.

Reference:

https://learn.microsoft.com/en-us/power-platform/admin/backup-restore-environments?tabs=new

Cheers,

PMDY

Want to check if you have added metadata to the entity in Power Apps – Table Segmentation properties?

Hi Folks,

After a break, I am back with my next blog post, this is a very short one.

Whenever you were working on any implementation, you could have added entity assets to the solution, many people miss adding metadata for the entity, since they don’t have a way to check properly, folks end up removing and readding the entity with metadata toggle on.

But don’t worry, here is a simple way to check this..

Let’s say you have added a table to the form like below

Now you want to add the metadata for this, click on the table name below

Click on Elipses…

Choose table segmentation as shown above

So as highlighted above, you can include all the objects or include table metadata.

Hope this small tip helps…so even if you miss adding metadata, you can safely add it later at any point of time.

Cheers,

PMDY

Fix Plugin Registration Tool Connection Issues with Multi-Factor Authentication (MFA) Enabled in Dynamics 365

Hi Folks,

It’s been a since I posted on Dynamics 365 Plugins, so this blog post talks about one small tip when connecting to your Dynamics 365 instance from Plugin Registration Tool either if you were connecting from Standalone Plugin Registration Tool or using Plugin Registration Tool from XrmToolBox.

If you were looking to install plugin registration tool itself, you can check the below post or if you want to learn about all Plugin related issues at once, you can check the references at the bottom of this post, else you can continue reading this post.

If you don’t know this tip, it will be difficult and least you will spend many minutes figuring out the error message you see in the Plugin registration tool.

This is applicable for applications who have MFA enabled, even if you haven’t enabled, it was enabled by Microsoft by default to enforce security.

As usually, you select:

  1. Office 365
  2. Enable Display list of available organizations, Show Advanced
  3. Provide User Name, Password
  4. Click on Login

You will be prompted this error in such case

======================================================================================================================
Source : Microsoft.IdentityModel.Clients.ActiveDirectory
Method : MoveNext
Date : 12/4/2025
Time : 5:09:52 pm
Error : AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access '00000007-0000-0000-c000-000000000000'. Trace ID: 7a7cac23-056c-4e77-ba82-98d50c0b7001 Correlation ID: d8b32fe6-6197-4d9a-a460-3834c8dc292a Timestamp: 2025-04-12 09:09:52Z
Stack Trace : at Microsoft.Xrm.Tooling.Connector.CrmWebSvc.ProcessAdalExecption(Uri serviceUrl, ClientCredentials clientCredentials, X509Certificate2 userCert, UserIdentifier& user, String clientId, Uri redirectUri, PromptBehavior promptBehavior, String tokenCachePath, Boolean isOnPrem, String authority, Uri& targetServiceUrl, AuthenticationContext& authContext, String& resource, CrmLogEntry logSink, Boolean useDefaultCreds, String& authToken, AdalException adalEx)
at Microsoft.Xrm.Tooling.Connector.CrmWebSvc.ExecuteAuthenticateServiceProcess(Uri serviceUrl, ClientCredentials clientCredentials, X509Certificate2 userCert, UserIdentifier user, String clientId, Uri redirectUri, PromptBehavior promptBehavior, String tokenCachePath, Boolean isOnPrem, String authority, Uri& targetServiceUrl, AuthenticationContext& authContext, String& resource, UserIdentifier& userIdent, CrmLogEntry logSink, Boolean useDefaultCreds, SecureString clientSecret)
at Microsoft.Xrm.Tooling.Connector.CrmWebSvc.DiscoverGlobalOrganizations(Uri discoveryServiceUri, ClientCredentials clientCredentials, X509Certificate2 loginCertificate, UserIdentifier user, String clientId, Uri redirectUri, PromptBehavior promptBehavior, String tokenCachePath, Boolean isOnPrem, String authority, UserIdentifier& userOut, CrmLogEntry logSink, Boolean useGlobalDisco, Boolean useDefaultCreds)
at Microsoft.Xrm.Tooling.Connector.CrmWebSvc.DiscoverOrganizations(Uri discoveryServiceUri, ClientCredentials clientCredentials, UserIdentifier user, String clientId, Uri redirectUri, PromptBehavior promptBehavior, String tokenCachePath, Boolean isOnPrem, String authority, UserIdentifier& userOut, CrmLogEntry logSink, Boolean useGlobalDisco, Boolean useDefaultCreds)
at Microsoft.Xrm.Tooling.CrmConnectControl.CrmConnectionManager.QueryOAuthDiscoveryServer(Uri discoServer, ClientCredentials liveCreds, UserIdentifier user, String clientId, Uri redirectUri, PromptBehavior promptBehavior, String tokenCachePath, Boolean useGlobalDisco)
at Microsoft.Xrm.Tooling.CrmConnectControl.CrmConnectionManager.QueryOnlineServerList(ObservableCollection`1 svrs, OrganizationDetailCollection col, ClientCredentials liveCreds, Uri trimToDiscoveryUri, Uri globalDiscoUriToUse)
at Microsoft.Xrm.Tooling.CrmConnectControl.CrmConnectionManager.FindCrmOnlineDiscoveryServer(ClientCredentials liveCreds)
at Microsoft.Xrm.Tooling.CrmConnectControl.CrmConnectionManager.ValidateServerConnection(CrmOrgByServer selectedOrg)
======================================================================================================================
Inner Exception Level 1 :
Source : Not Provided
Method : Not Provided
Date : 12/4/2025
Time : 5:09:52 pm
Error : Response status code does not indicate success: 400 (BadRequest).
Stack Trace : Not Provided
======================================================================================================================
Inner Exception Level 2 :
Source : Not Provided
Method : Not Provided
Date : 12/4/2025
Time : 5:09:52 pm
Error : {"error":"interaction_required","error_description":"AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access '00000007-0000-0000-c000-000000000000'. Trace ID: 7a7cac23-056c-4e77-ba82-98d50c0b7001 Correlation ID: d8b32fe6-6197-4d9a-a460-3834c8dc292a Timestamp: 2025-04-12 09:09:52Z","error_codes":[50076],"timestamp":"2025-04-12 09:09:52Z","trace_id":"7a7cac23-056c-4e77-ba82-98d50c0b7001","correlation_id":"d8b32fe6-6197-4d9a-a460-3834c8dc292a","error_uri":"https://login.microsoftonline.com/error?code=50076","suberror":"basic_action"}: Unknown error
Stack Trace : Not Provided
======================================================================================================================
======================================================================================================================
Inner Exception Level 2	: 
Source	: Not Provided
Method	: Not Provided
Date	: 12/4/2025
Time	: 5:09:52 pm
Error	: {"error":"interaction_required","error_description":"AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access '00000007-0000-0000-c000-000000000000'. Trace ID: 7a7cac23-056c-4e77-ba82-98d50c0b7001 Correlation ID: d8b32fe6-6197-4d9a-a460-3834c8dc292a Timestamp: 2025-04-12 09:09:52Z","error_codes":[50076],"timestamp":"2025-04-12 09:09:52Z","trace_id":"7a7cac23-056c-4e77-ba82-98d50c0b7001","correlation_id":"d8b32fe6-6197-4d9a-a460-3834c8dc292a","error_uri":"https://login.microsoftonline.com/error?code=50076","suberror":"basic_action"}: Unknown error
Stack Trace	: Not Provided
======================================================================================================================

Based on the above inner exception, we can clearly understand that it is looking for Multifactor Authentication, so untick the Show Advanced checkbox, it then asks for Multifactor Authentication as shown below.

That’s it, with this simple tick of unchecking the Show Advanced, you were able to overcome this error, how cool is it…?

I have written lot of articles with respect to Plugin registration tool, you can check them below

Issues related to Plugins and Plugin Registration Tool

Hope this helps…

Cheers,

PMDY

Encrypting/Decrypting a file using Public & Private Key Pair with GnuPG

Hi Folks,

Thank you for visiting my blog today…this is post is mainly for Pro developers. Encryption is crucial to maintain the confidentiality in this digital age for the security of our sensitive information. So here is a blog about it. This is in continuation to my previous blog post on encrypting files using GnuPG.

In this blog post, I will give you sample how you can encrypt/decrypt using GnuPG with command line scripts from C# code.

If you didn’t go through my previous article, I strongly recommend you go through that article below first to understand the background.

Next, in order to encrypt/decrypt a given csv file (taken for simplicity), we can use the following C# codes. For illustration purpose, I have just provided you the logic in the form of a Console.

Encryption:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
namespace eHintsBatchDecryptionTest
{
class Program
{
static void Main(string[] args)
{
string gpgPath = @"D:\Softwares\Kleo Patra\GnuPG\bin\gpg.exe"; //This is the place where you have installed GnuPG Software
string inputFile = "location of input file";
string outputFile = "location of output file";
string passphrase = "passPhrase";
DecryptGPGFile(gpgPath, inputFile, outputFile, passphrase);
}
static void DecryptGPGFile(string gpgPath, string inputFile, string outputFile, string passphrase)
{
using (Process process = new Process())
{
process.StartInfo.FileName = gpgPath;
process.StartInfo.Arguments = $"–batch –yes –pinentry-mode=loopback –passphrase {passphrase} -d -o \"{outputFile}\" \"{inputFile}\"";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
process.WaitForExit();
if (process.ExitCode == 0)
{
Console.WriteLine("Decryption successful.");
}
else
{
Console.WriteLine("Decryption failed. Error: " + error);
}
}
}
}
}

Decryption:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
namespace BatchDecryptionTest
{
class Program
{
static void Main(string[] args)
{
string gpgPath = @"D:\Softwares\Kleo patra\GnuPG\bin\gpg.exe";//Once GPG installed, you can look for gpg.exe in the bin folder of the installation
string inputFile = "Input encrypted file";//Replace with your gpg encrypted file location
string outputFile = "Decrypted CSV file"; //give it a name for the decrypted file and location, output file path doesnt exists yet, you may give a sample name
string passphrase = "passPhrase";
DecryptGPGFile(gpgPath, inputFile, outputFile, passphrase);
}
static void DecryptGPGFile(string gpgPath, string inputFile, string outputFile, string passphrase)
{
using (Process process = new Process())
{
process.StartInfo.FileName = gpgPath;
process.StartInfo.Arguments = $"–batch –yes –pinentry-mode=loopback –passphrase {passphrase} -d -o \"{outputFile}\" \"{inputFile}\""; //Pass the PassPhrase, Input and Output file paths as parameters
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
process.WaitForExit();
if (process.ExitCode == 0)
{
Console.WriteLine("Decryption successful.");
}
else
{
Console.WriteLine("Decryption failed. Error: " + error);
}
}
}
}
}

All you need is to copy and replace the file locations in the code. Sit back and enjoy encrypting and decrypting with GnuPG. I should say once known, this is the easiest way to encrypt/decrypt from C# code, no strings attached.

If you need any other information, please do let me know in comments.

Cheers,

PMDY

When to use NO-LOCK in SQL – Quick Review

Hi Folks,

Well this post is not related to Power Platform, but I want to bring it on here to specify the significance of using NOLOCK in Power Platform Implementations using SQL Server.

Recently during our Deployment activity, we had a SSIS job which is writing a lot of data into SQL Server, at the same time, we were trying to read the data from the same table. I received never ending Executing query … message. It is when I had arguments on this, hence I would like to share the significance of NOLOCK.

The default behaviour in SQL Server is for every query to acquire its own shared lock prior to reading data from a given table. This behaviour ensures that you are only reading committed data. However, the NOLOCK table hint allows you to instruct the query optimizer to read a given table without obtaining an exclusive or shared lock. The benefits of querying data using the NOLOCK table hint is that it requires less memory and prevents deadlocks from occurring with any other queries that may be reading similar data. 

In SQL Server, the NOLOCK hint, also known as the READUNCOMMITTED isolation level, allows a SELECT statement to read data from a table without acquiring shared locks on the data. This means it can potentially read uncommitted changes made by other transactions, which can lead to what’s called dirty reads.

Here’s an example:

Let’s say you have a table named Employee with columns EmployeeID and EmployeeName.

CREATE TABLE Employee (
    EmployeeID INT,
    EmployeeName VARCHAR(100)
);

INSERT INTO Employee (EmployeeID, EmployeeName)
VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Charlie');

Now, if two transactions are happening concurrently:

Transaction 1:

BEGIN TRANSACTION
UPDATE Employee
SET EmployeeName = 'David'
WHERE EmployeeID = 1;

Transaction 2:

SELECT EmployeeName
FROM Employee WITH (NOLOCK)
WHERE EmployeeID = 1;

If Transaction 2 uses WITH (NOLOCK) when reading the Employee table, it might read the uncommitted change made by Transaction 1 and retrieve 'David' as the EmployeeName for EmployeeID 1. However, if Transaction 1 rolled back the update, Transaction 2 would have obtained inaccurate or non-existent data, resulting in a dirty read.

Key takeaways about NOLOCK:

  • Pros: Reduces memory use, avoids blocking, speeds up reads.
  • Cons: May read uncommitted or inconsistent data.

Using NOLOCK can be helpful in scenarios where you prioritize reading data speed over strict consistency. So, in my case as I want to just view the data, using NOLOCK is good without locking the query. However, it’s essential to be cautious since it can lead to inconsistent or inaccurate results, especially in critical transactional systems.

Other considerations like potential data inconsistencies, increased chance of reading uncommitted data, and potential performance implications should be weighed before using NOLOCK.

Conclusion:

There are benefits and drawbacks to specifying NOLOCK table hint as a result they should not just be included in every T-SQL script without a clear understanding of what they do. Nevertheless, should a decision be made to use NOLOCK table hint, it is recommended that you include the WITH keyword. Using NOLOCK without WITH Statement is deprecated. Always use a COMMIT keyword at the end of the transaction.

Hope this helps…

Cheers,

PMDY

Microsoft.Xrm.RemotePlugin.Grpc.SandboxFabricGrpcClient error from Plugin in Dynamics 365 – Quick Review

Hi Folks,

I have been encountering a strange error since past few weeks now. If you search for this error in Internet you find nothing…the detailed error message obtained from the Plugin Trace Log is as below

System.ServiceModel.FaultException`1[Microsoft.Xrm.Sdk.OrganizationServiceFault]: Exception occured ... at Microsoft.Xrm.RemotePlugin.Grpc.SandboxFabricGrpcClient.ExecutePluginInternal(IRemotePluginRequest pluginRequest, ExecuteRequest executeRequest, Guid executionId, ISandboxFabricDuplexCommunicationHandler communicationHandler, Boolean returnTraceInfo, Guid organizationId, SandboxFabricCallTracker sandboxFabricCallTracker) +0x5d0
at Microsoft.Xrm.RemotePlugin.Grpc.SandboxFabricGrpcClient.ExecutePlugin(IRemotePluginRequest pluginRequest, IPluginExecutionContext executionContext, IPluginTracingService pluginTracingService, ISandboxFabricDuplexCommunicationHandler communicationHandler, ISet`1 earlySerializedPropertiesList, SandboxFabricCallTracker sandboxFabricCallTracker, ISandboxMemoryStreamProvider memoryStreamProvider) +0x2cd
at Microsoft.Xrm.RemotePlugin.Grpc.SandboxFabricCodeUnit.Execute(ILifetimeScope scope, IExecutionContext context, SandboxFabricCallTracker& sandboxFabricCallTracker, ISandboxMemoryStreamProvider memoryStreamProvider) +0x6e
at Castle.Proxies.Invocations.ISandboxFabricCodeUnit_Execute.InvokeMethodOnTarget() +0x13
at Castle.DynamicProxy.AbstractInvocation.Proceed() +0x2d
at Microsoft.Xrm.RemotePlugin.Client.Interceptors.SandboxFabricPluginTraceInterceptor.Intercept(IInvocation invocation, IExecutionContext context, SandboxFabricCallTracker sandboxFabricCallTracker) +0x1f

The error message looked so strange to me and I couldn’t get any idea on what is happening, I thought some problem with the Plugin Code and it was executing more than 2 mins and hence causing error related to Sandbox service of Dynamics 365. I was executing this logic placed inside an action from Power Automate…this took couple of hours to figure out what was happening…

With no clue, I had started to change Plugin Code in the following ways…

  1. Change the Synchronous Plugin to Asynchronous Plugin
    • It doesn’t show any error in Power Automate now, but in the Plugin Trace Log, it still throws the error
  2. Add Try – Catch Block
    • Add try catch block made me understood that Plugin was causing an exception due to type casting issue in my logic. This worked…

FYI, I have removed some sensitive information from the below error message.

Microsoft recommends us to use Try – Catch block for efficient error handling, in the first place, so always use proper error handling while developing Plugins, Actions or Custom Workflows in Dynamics 365 to avoid such errors.

If you face this kind of error, this is some issue within your code and nothing to do with Microsoft Services, no need to raise a Microsoft Support Ticket for resolving this.

Hope this helps someone facing the same issue…

Cheers,

PMDY

Seatrium Learning Day – 3 Day Event

Hi Folks,

Excited to share about the recently held AI Innovation Day Bootcamp and Hackathon 2 day event organized by Microsoft, Singapore on September at Seatrium, 80 Tuas S Blvd, Singapore, SG, 6265 1766.

🗣️ Business User Feedback & Reflections

Solutions buit by Seatrium employees based on the engagement and the type, thanks to David Choo, Seatrium Microsoft Technical Account Manager for spearheading this Initiative.

Seatrium management officially sent a thank you note to MVPs Pavan Mani Deep Yaragani, Goloknath Mishra, Senthami Selvan for spending 3 valuable days for this event making it a grand success.

The event took place like below

  1. Day Microsoft Singapore with Seatrium Hackathon Particpants for prepartion on 16 September
  2. AI Innovation Day – 1 – 23 September, 2024.
  3. AI Innovation Day – 2 – 24 September, 2024.
  4. AI Innovation Day – Evaluation and Awards

Below were some the feedback from different business user teams.

🛠️ Operations & Production Team:

“We’ve been struggling with manual job task cards for years—seeing OCR and Copilot Studio digitize it in just two days was mind-blowing!”

“Tracking welder certifications used to take hours each week. Now, with this Power App, we can do it in seconds.”

📦 Supply Chain:

“This predictive maintenance idea using AI was something we thought only big tech could do. I didn’t expect we could prototype it so fast with Azure AI and Power Platform!”

“The Power BI dashboards finally give us a single view of procurement metrics without needing to export Excel sheets all day.”

🏗️ Engineering:

“We’ve been manually cross-checking MTOs and standards forever—having AI do that gives us back our time to actually focus on engineering work.”

“It’s amazing to see a tool extract information from drawings and relate it to VCDs without manual effort.”

💻 Group IT & HR:

“That SharePoint Copilot FAQ bot is going to save us a ton of IT support emails—super impressive.”

“Invoice checking and validation was one of our most time-consuming tasks—now it’s automated and way more reliable.”

📊 Commercial & Planning:

“We finally saw what Microsoft Fabric can do for project-level KPIs and dashboards. We’re excited to explore more.”

“This was one of the most hands-on, practical hackathons we’ve had. It wasn’t just ideas, we actually saw working solutions.”

The teams have worked on the attached use cases:

Fantastic event Pics:

Looking forward to more collaborations with Microsoft for organizing such events in Singapore.

Cheers,

PMDY

Polymorphic Lookup in Dynamics 365: Streamlining Your CRM with Flexible Relationships

In Dynamics 365, a Polymorphic Lookup is a powerful feature that allows you to associate a single lookup field with multiple different entities. This feature is particularly useful when you want a field to reference multiple related entities, providing greater flexibility and efficiency in your CRM applications.

What is a Polymorphic Lookup?

A Polymorphic Lookup is a special type of lookup field that can refer to multiple entities rather than just one. For example, a single “Related Entity” field can refer to either a Contact, Account, or Opportunity, making it versatile for various business scenarios. This capability is referred to as “polymorphism” because the lookup field can resolve to different types of entities at runtime.

Example Scenario:

Consider a sales scenario where a “Related Entity” can be a Customer, but the customer could be either an Account or a Contact. Rather than having two separate lookup fields (one for Account and another for Contact), you can create a polymorphic lookup field, which makes your user interface simpler and more streamlined.

How Does Polymorphic Lookup Work in Dynamics 365?

In Dynamics 365, polymorphic lookup fields are implemented as part of the Relationship between entities. The key concept here is the EntityReference, which dynamically resolves to the appropriate entity type (e.g., Account, Contact, etc.) based on the actual value selected by the user.

  1. Field Definition:
    • When defining a lookup field, you define a Relationship where the field can refer to multiple target entities.
    • The system uses the Type and Id to determine the related entity.
  2. Lookup Resolution:
    • At runtime, when a user selects a value in the polymorphic lookup field, the system dynamically resolves which type of entity to link to.
    • The field displays the appropriate name (e.g., Account or Contact) based on the entity that the user selects.

Creating Polymorphic Lookups in Dynamics 365

Polymorphic lookup fields are typically used in the following types of scenarios:

  • Custom Relationships: When you need to create a lookup that can reference multiple different entities.
  • Shared Relationship: For cases where one relationship applies to more than one entity, such as a lookup that could refer to either a Contact or an Account.
Steps to Create a Polymorphic Lookup Field:
  1. Navigate to the Customization Area:
    • Go to the Settings area in Dynamics 365 and select Customizations.
    • Select Customize the System to open the solution where you want to add the polymorphic lookup field.
  2. Create a New Field:
    • In the relevant entity, click on Fields, and then select New.
    • Choose the Lookup data type for the field.
  3. Define the Polymorphic Lookup:
    • Under the Related Entity section, select Custom to define the multiple entities this lookup should support.
    • Select the Entity Relationships where this lookup should point to multiple entities.
  4. Save and Publish:
    • Save the field and publish your customizations to apply the changes.

Example: Setting Up Polymorphic Lookup for Customer

Suppose you’re designing a custom Case entity and you want to add a lookup for the Customer. Instead of creating separate lookups for Contact and Account, you can create a polymorphic lookup that links to either an Account or Contact as the Customer.

Steps:
  • Create a Customer Lookup field in the Case entity.
  • Define the Customer Lookup field to support both Account and Contact entities.
  • After publishing the field, the user will see the lookup field and will be able to choose either an Account or Contact as the Customer.

Use Cases for Polymorphic Lookup

  1. Consolidating Related Data:
    • Polymorphic lookups help streamline user experience by consolidating multiple lookups into a single field, especially when dealing with common relationships across different entities.
  2. Reducing Redundancy:
    • Rather than having separate lookup fields for Account and Contact in every related form, you can reduce redundancy by using polymorphic lookups, which allows referencing both entities in one field.
  3. Improved Reporting and Analytics:
    • When data is related across multiple entities, using a polymorphic lookup can make it easier to pull reports and perform analysis without requiring multiple joins or complex queries.

Considerations and Limitations

While polymorphic lookups are powerful, they come with certain limitations:

  • Limited to Certain Fields: Polymorphic lookups are supported only in certain system fields (like Regarding in activities), but may not be available for every custom scenario.
  • API Handling: When working with the Dynamics 365 Web API, the polymorphic lookup is handled through special attributes that require careful parsing to identify the correct entity type.
  • UI Considerations: Although polymorphic lookups streamline the user interface, they can also confuse users who are unfamiliar with the concept. It’s important to have clear documentation and training for users on how to use these fields.

Conclusion

Polymorphic lookups in Dynamics 365 provide an elegant solution for scenarios where a lookup field needs to refer to multiple entity types. By understanding and using polymorphic lookups effectively, you can streamline your CRM solutions, reduce redundancy, and improve your application’s flexibility. It’s important to consider the limitations and ensure that users are properly guided in utilizing these fields within your system.

You can easily create this Polymorphic Lookup from XrmToolBox as well…

https://pascalcase.com/Home/Blog/understanding-and-using-polymorphic-lookups-in-dynamics-365-with-xrmtoolbox

Hope this helps.

Cheers,

PMDY

Paste JSON/XML as classes in Visual Studio – Quick Tip

Hi Folks,

With this post I will show you how you can quickly add classes for your JSON and XML in Power Platform using Visual Studio.

Sometimes, there will be requirements where you need to convert and replace your Power Automate Flows with custom code either using Plugins or Actions. In this case, you may definitely need to parse the response returned by REST API calls and you might need to create relevant classes to hold the parameters and attributes, creating these manually would be cumbersome and takes few minutes of time even for a good developer.

Here I am taking the example using JSON.

So, without further due, let’s see in this in action.

Step 1: So, just copy using Cntrl + C shortcut, this is mandatory, else you will not able to see the Paste JSON as Classes and Paste XML as classes under edit..

{
"orderId": "ORD123456",
"customerName": "John Doe",
"orderDate": "2024-04-27T08:30:00Z",
"items": [
{
"itemId": "ITEM001",
"itemName": "Product A",
"quantity": 2,
"unitPrice": 25.99
},
{
"itemId": "ITEM002",
"itemName": "Product B",
"quantity": 1,
"unitPrice": 35.50
}
],
"totalAmount": 87.48,
"shippingAddress": {
"street": "456 Elm St",
"city": "Metropolis",
"zipcode": "54321",
"country": "USA"
},
"status": "Shipped"
}

Step 2: Then open Visual Studio –> Edit –> Paste Special

Step 3: Click on Paste JSON As Classes and soon you should be able to see something as below.

That’s it, your classes are now generated from the copied JSON File, you can do pretty much the similar thing with XML.

Hope this helps someone trying to achieve a similar goal…

Cheers,
PMDY