Saturday, March 14, 2026

Building a Custom Plugin in Dataverse and Calling It from Power Automate

Building a Custom Plugin in Dataverse and Calling It from Power Automate

A step-by-step guide for developers

March 2026  |  Power Platform Series

What Are We Building?

In this post, we will walk through how to write a simple C# plugin, register it in Microsoft Dataverse, expose it as a custom API action, and finally call it from Power Automate as an unbound action.

To keep things simple, our plugin will do one thing: add two numbers together. The formula is:

 

  a = b + c

 

Simple math — but the plumbing around it covers everything you need to know to build real-world business logic in Dataverse.

 

What You Need Before Starting

Tool

Why You Need It

Visual Studio

Write and build the C# plugin

Power Platform / Dataverse environment

Deploy and test the plugin

Plugin Registration Tool (PRT)

Register the DLL in Dataverse

.NET Framework 4.6.2

Required target framework for Dataverse plugins

Microsoft.CrmSdk.CoreAssemblies (NuGet)

Gives you IPlugin and Dataverse base classes

 

Important: Dataverse plugins only support .NET Framework 4.6.2. Do NOT use .NET 5, 6, 7, or 8. This is the most common mistake developers make.

 

Step 1 — Create the Visual Studio Project

Open Visual Studio and create a new project:

1.    File > New > Project

2.    Choose Class Library (.NET Framework)

3.    Set the target framework to .NET Framework 4.6.2

4.    Name the project — for example, MyCalcPlugin

 

Then install the Dataverse SDK via NuGet Package Manager Console:

Install-Package Microsoft.CrmSdk.CoreAssemblies

 

After installing, confirm the DLL reference path contains 'net462' — for example: packages\Microsoft.CrmSdk.CoreAssemblies.9.x.x\lib\net462\Microsoft.Xrm.Sdk.dll

 

Step 2 — Write the Plugin Code

Replace the default class with this code. The plugin reads two input parameters (b and c), adds them together, and writes the result to an output parameter (a).

 

using Microsoft.Xrm.Sdk;

using System;

 

namespace MyCalcPlugin

{

    public class AddNumbers : IPlugin

    {

        public void Execute(IServiceProvider serviceProvider)

        {

            var context = (IPluginExecutionContext)

                serviceProvider.GetService(typeof(IPluginExecutionContext));

 

            var tracer = (ITracingService)

                serviceProvider.GetService(typeof(ITracingService));

 

            try

            {

                decimal b = (decimal)context.InputParameters["b"];

                decimal c = (decimal)context.InputParameters["c"];

                decimal a = b + c;

 

                context.OutputParameters["a"] = a;

                tracer.Trace($"Result: {b} + {c} = {a}");

            }

            catch (Exception ex)

            {

                throw new InvalidPluginExecutionException($"Error: {ex.Message}");

            }

        }

    }

}

 

Build the project in Release mode. Your DLL will be in the bin\Release\ folder.

 

Step 3 — Sign the Assembly (Required)

Dataverse requires all plugin DLLs to be strongly signed. Without signing, the Plugin Registration Tool will reject the file.

5.    Right-click the project in Solution Explorer > Properties

6.    Go to the Signing tab

7.    Check 'Sign the assembly'

8.    In the dropdown, choose New... and create a key file (e.g. MyCalcPlugin.snk)

9.    Leave password protection unchecked for simplicity

10. Click OK, then Clean Solution and Rebuild

 

To verify the signing worked, run this in a Developer Command Prompt from the bin\Release\ folder:

sn.exe -v MyCalcPlugin.dll

 

You should see: Assembly 'MyCalcPlugin.dll' is valid. If you see 'Strong name validation failed', delete bin\ and obj\ folders and do a full Rebuild.

 

Step 4 — Create the Custom Action in Dataverse

The Custom Action is what creates the message that your plugin listens to. Think of it as the API contract — it defines the input and output parameters.

11. Go to make.powerapps.com and open your solution

12. Click New > Automation > Process

13. Set Category to Action and Entity to None (global) — this makes it unbound

14. Give it a name, for example AddNumbers

 

Then add parameters in the Process Arguments section:

 

Name

Direction / Type / Required

b

Input | Decimal Number | Required

c

Input | Decimal Number | Required

a

Output | Decimal Number

 

Save and Close, then click Activate. The unique name of your action (visible in the Name field) will look like new_AddNumbers — note this name, you will need it in the next steps.

 

Do not add any workflow steps inside the action designer. The plugin handles the logic — the action just defines the parameters.

 

Step 5 — Register the Plugin in PRT

The Plugin Registration Tool (PRT) connects your DLL to Dataverse. You can get it from NuGet or install via the Power Platform Tools extension in Visual Studio.

 

Register the Assembly

15. Open PRT and connect to your Dataverse environment

16. Click Register > Register New Assembly

17. Browse to your bin\Release\MyCalcPlugin.dll

18. Select Isolation Mode: Sandbox and Storage: Database

19. Click Register Selected Plugins

 

Register a Step on the Plugin

20. In the left tree, expand (Assembly) MyCalcPlugin

21. Right-click MyCalcPlugin.AddNumbers > Register New Step

22. Fill in the step details as shown below:

 

Field

Value

Message

new_AddNumbers  (your action's unique name)

Primary Entity

(leave blank — unbound action)

Event Handler

MyCalcPlugin.AddNumbers

Eventing Pipeline Stage

Post-operation

Execution Mode

Synchronous

 

23. Click Register New Step

 

Always right-click the plugin class node to register a step. If you use the top toolbar instead, the Event Handler dropdown will be blank and registration will fail.

 

Step 6 — Call the Action from Power Automate

Now that everything is wired up, you can call the action from a flow.

24. Create a new flow in Power Automate

25. Add a new action and search for Perform an unbound action (Dataverse connector)

26. In the Action Name field, type your action's unique name: new_AddNumbers

27. The input fields b and c will appear — map them to values or dynamic content

28. In the next step, reference the output like this:

 

outputs('Perform_an_unbound_action')?['body/a']

 

If new_AddNumbers does not appear in the dropdown, the action is still in Draft state. Go back to make.powerapps.com and Activate it first.

 

Common Errors and How to Fix Them

Error

Fix

Could not load assembly System.Runtime Version=8.0.0.0

Wrong target framework. Change project to .NET Framework 4.6.2 and rebuild.

Assemblies must be strongly signed

Go to project Properties > Signing tab, enable signing, create a .snk key file, and rebuild.

Strong name validation failed (0x8013141A)

Delete bin\ and obj\ folders, clean solution, rebuild. Or run: sn.exe -Vr *

Invalid Message Name in PRT

The Custom Action has not been created in Dataverse yet. Create and activate the action first.

Plugin was not specified (required field)

You used the top toolbar to register the step. Right-click the plugin class node instead.

No values matching your search in Flow

Action is in Draft state or wrong unique name used. Activate the action and use the prefix e.g. new_AddNumbers.

 

How It All Fits Together

Here is a high-level view of the full architecture:

 

  C# Class Library (.NET Framework 4.6.2)

          |

          |  Build signed .dll

          v

  Plugin Registration Tool

          |

          |  Register assembly + step on message

          v

  Dataverse Custom Action  (new_AddNumbers)

          |

          |  Exposes as Web API endpoint

          v

  Power Automate  ->  Perform an unbound action

          |

          v

  Returns: a = b + c

 

Wrapping Up

To summarise what we covered:

      Write a C# plugin targeting .NET Framework 4.6.2

      Sign the assembly with a strong name key (.snk)

      Create a Custom Action in Dataverse to define input/output parameters

      Register the plugin DLL and a step in the Plugin Registration Tool

      Call the action from Power Automate using the Perform an unbound action connector

 

This pattern works for any business logic you want to centralise in Dataverse — validation, calculations, integrations, and more. Once the plugin is registered, it can be called from flows, canvas apps via Power Pages, or directly via the Web API.

The diagram shows the full journey:

  1. C# Plugin — code + signing
  2. Plugin Registration Tool — deploy the DLL
  3. Dataverse Custom Action — the API contract
  4. Web API endpoint — what gets exposed
  5. Power Automate — where you consume it

Happy coding!


No comments:

Post a Comment

Featured Post

Automate SharePoint List CRUD Operations Using PowerShell, Microsoft Graph API & GitHub Actions

Automate SharePoint List CRUD Operations Using PowerShell, Microsoft Graph API & GitHub Actions App-only Auth with Certificate   |  ...

Popular posts