Wednesday, October 24, 2018

Dynamics 365 Custom Actions - Bound and Unbound with Xrm.WebApi.online.execute()

Hello World,

It all started when I tried to use Xrm.WebApi.online.execute() method to call CRM Custom Action from Custom Web Resource.
https://docs.microsoft.com/en-gb/dynamics365/customer-engagement/developer/clientapi/reference/xrm-webapi/online/execute.
Instead calling the CRM actions by manually making XmlHttpRequests, below seems to be easy to code.

Xrm.WebApi.online.execute(request).then(successCallback, errorCallback);

Isn't it obvious to select above instead of below hazzard,

var req = new XMLHttpRequest();
req.open("POST", actionUrl, false);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.onreadystatechange = function () {
req.setRequestHeader("OData-Version", "4.0");
    if (this.readyState == 4 /* complete */) {
   req.onreadystatechange = null;
        if (this.status == 200 || this.status == 204) {
   // get output
  }
 }
}

Xrm.WebApi that came with V9 provides number of methods like, createRecord, deleteRecord, retrieveRecord, retrieveMultipleRecords, updateRecord, execute and executeMultiple. Create/Update and Retrive was quiet easy to use.

To call custom actions, we can use Xrm.WebApi.online.execute() method, and below is where I got stuck.



In making the request object, how to specify the bound parameter? First of all what's bound/ unbound action?

Unbound Action is nothing but, the Global Action, which is not bound to any Entity :D. Therefore Bound Actions are Actions with a specific Entity.

Now below is an Action bound to Contact Entity.



Now calling Unbound Actions is easy, just use boundParameter: null


For Bound Actions, how to specify the BoundParameter?


To understand how your Action actually takes it's boundParameter and other Input/Output parameters, download the OData Metadata file from Customizations --> Developer Resources. And below is what we get for above sample action.

<Action Name="msdyn_GDPROptoutContact" IsBound="true">
    <Parameter Name="entity" Type="mscrm.contact" Nullable="false" />
    <Parameter Name="optout" Type="Edm.Boolean" Nullable="false" />
</Action>

Now you can see that in-addition to Input/Output parameters, we have a parameter named as "entity". Actually this is documented here in https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/webapi/use-web-api-actions, but we tend to miss it, first time we read.

So now when making your request object for Xrm.WebApi.online.execute() method, treat "entity" as a parameter.

For example below is how you should code the request object for above action.

var target = { entityType: "contact", id: "69DA0233-2D96-W891-B93F-207D7B3BF6C8" }; var reqObject = {}; reqObject.entity = target; reqObject.optout = true; reqObject.getMetadata = function () { return { boundParameter: "entity", operationType: 0, operationName: "msdyn_GDPROptoutContact", parameterTypes: { "entity": { typeName: "mscrm.contact", structuralProperty: 5 }, "optout":{typeName: "Edm.Boolean", structuralProperty: 1} } } };

For me this is a life saving solution :)

Thanks for reading this long.

1 comment:

  1. Thank you for posting this. It's the best answer to this problem that I've been able to find. And it works !

    It's strange that as a full-time Microsoft employee working on Dynamics applications, I don't have access to documentation that explains how to do this, and I have to resort to searching the web for other people who have figured this out.

    ReplyDelete