top of page
  • Writer's pictureAndres Biarge

Implementing Business Logic customizing the Dataverse Event Framework (1): Custom Actions

This article is the first in a series where I'll write about Dataverse's Event Framework. There are many different ways of implementing business logic in the Power Platform and we try to favor the most Low-Code approach. So, we automatically point to Power Automate, but there are many other options not often considered that can even help you create a more modular architecture.

In this post, I'll try to explain (with a use case) the Low Code approach for using the Event Framework in our favor.

What is the Event Framework and why should I care?

When leveraging Dataverse, the usual maker creates automations (e.g., Power Automate Flows) by using the out-of-the-box triggers: create / delete / modify / update. Well, let's put some names: those "triggers" are called "verbs", and you can create your own verbs as well.

Why would this be useful? Well, it allows us to create our own business logic in a more decoupled manner. Let's imagine the example:

  • We have an Invoice table, and we want to trigger an approval process when the invoice is "reviewed" (Status Reason) and certain conditions are met.

  • These conditions consider values from columns like "amount", "date", or even will check information on a lookup column (like "provider").

  • If the conditions are met, some logic will happen, and an approval will be sent.

The usual maker would try to put all those conditions in the trigger or maybe try to separate the conditions from the logic into a child flow (which doesn't work very well with a sane ALM). And what happens when the conditions need changing? It can mess a lot with the flow we just built.

If only we could wrap the trigger for our logic to something like "when an Invoice needs reviewing". This is when creating your own event comes handy.

How does it work?

Basically, every data operation that takes place inside Dataverse will trigger an event. Think of them as the "primitives" types of events: Create, Retrieve, RetrieveMultiple, Update, Delete, Associate and Disassociate.

For every event, you can register your own logic (step) in one of the following stages of the event. Let's use the Create event as an example:

  1. PreValidation: this is when the columns are validated before the row is created. You can add your own validations and cancel the operation here.

  2. PreOperation: just before the record is created (we' already "inside" the database transaction). You can change values here, but it's not recommended to cancel the operation (it impacts performance).

  3. MainOperation: the record is created. We cannot add our own logic here (with some exceptions).

  4. PostOperation: just after the record has been created. This is when we trigger Power Automate flows.

You can read a much better and complete explanation here: Event Framework (Microsoft Dataverse) - Power Apps | Microsoft Learn

Note: if you have some JavaScript background, you may be familiar with Node.js' beautiful Event Loop. That can help you understand how this event-driven architecture work. However, bear in mind that Dataverse 's core is built on SQL Server, so you can leverage synchronous events as well (which is a LOT of responsibility, as you can wreck the performance of a WHOLE environment).

The Low-Code approach: using a Custom Action to create your own message

This is not a step-by-step guide as that job is already done in the documentation: Create a custom process action - Power Apps | Microsoft Learn, but I will provide you with some screenshots that you can follow:

What components do we need?

Following the scenario, I described above, we'll need:

  1. A synchronous workflow that will "trigger" our Custom Action when certain conditions are met. Putting some names here: it will send our custom "message" to be listened by whoever wants to inside the Power Platform environment.

2. The Custom Action itself. We define the custom message when setting up our Custom Action.

3. A Power Automate cloud flow that will execute the business logic and will be triggered when the custom message is sent.

The order I recommend you follow this approach is 2-1-3, as you'll need to define the Custom Action before configuring the synchronous workflow.

2. The Custom Action

We want to define a message that clearly tell us "The invoice has been already reviewed". So, put a name that will make sense in 2 months. Then, just add an input parameter: the reference to the invoice.

1. The Synchronous Workflow

Configure it so that it only triggers when the Status Reason changes, check that it is in the Review status, and then trigger the action.

3. The Power Automate cloud flow

You'll use the trigger "When an action is performed" (Microsoft Dataverse - Connectors | Microsoft Learn), and then go along with your business process.

Note: because of the way we've configured the Custom Action, we'll only receive the reference to the record (the GUID). So, be sure to retrieve the record if you need to work with other columns.

Where else can you trigger a Custom Action from?

These are many ways to trigger your Custom Action. Here are the main ones:

let serverURL = Xrm.Page.context.getClientUrl();
let actionName = "abg_IncomingInvoiceIsReviewed"; 
fetch(`${serverURL }/api/data/v9.2/${actionName}` ,
    method: "POST",
    headers: {
      "Accept": "application/json",
      "Content-Type":  "application/json;charset=utf-8",
      "OData-MaxVersion":  "4.0",
      "OData-Version":  "4.0"
    body: JSON.stringify({
      "IncomingInvoiceReference": {
        "abg_incominginvoiceid": "xxxxxxxxxx-xxxx-xxxx-xxxx-002248081d18"
).then((res) => {console.log(res))
.catch(err => console.error(err))
  • Invoking it (utilizing the Dataverse Web API).

Final comments

I hope I did a good job explaining to you how Custom Actions work. And, more importantly, why it's very useful to have them on your toolbelt.

In the next blog post, I'll try to showcase you a different way of adding business logic to your Power Platform-based solution.

Thanks for reading, truly. And please let me know your thoughts in the comments below.



72 views0 comments


Rated 0 out of 5 stars.
No ratings yet

Add a rating
bottom of page