Invoke an action in dynamics 365 – Xrm.WebApi with EntityReference, entity and entitycollection input parameters

Follow my blog for more interesting topics on Dynamics 365, Portals and Power Platform. For training and consulting, write to us at info@xrmforyou.com

Dynamics Version 9.0 introduced the Xrm.WebApi namespace which provides all the methods to interact with dynamics CRM server from client side script.
Detailed Documentation – https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/clientapi/reference/xrm-webapi
However recently I was working on a project to upgrade the SOAP calls from client and replace them with the new Xrm.WebApi methods. Create/ delete/ update were kind of easy and was easily ported to the new API’s.
However then came the Actions. The client had actions which had many input parameters and which were getting invoked from the client using SOAP calls. We had to port them to the Xrm.WebApi. But in Xrm.WebApi we did not had any function like executeAction. But the Xrm.WebApi.execute came to our rescue.
Let’s first examine Xrm.WebApi.execute method. Microsoft documentation shows it like this –
Xrm.WebApi.execute(request).then(successCallback, errorCallback);
For the sake of brevity of this blog post, I am skipping the documentation of the parameters. For detailed information on the parameters, please refer the below Microsoft documentation link – https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/clientapi/reference/xrm-webapi/execute
So how to call an action with input parameters? For this post, I created an action named “new_TestAction”. The action is global. It has the following input parameters.

  • Name – Type (string)
  • Age – Type(string)
  • InputEntityReference – Type (EntityReference)
  • InputEntity – Type (Entity)
  • InputEntityCollection – Type(EntityCollection)

For entityreference, entitycollection and entity, I have kept the Entity as Account Entity. All set and done. Now the next step is to call the action. below is the sample code to create the request object. All the important parameters has been highlighted and appropriate comments put.
TestAction1: function (input1, input2, inputEntityReference, inputAccount, inputAccountCollection) {
this.InputEntityReference = inputEntityReference;
this.Input1 = input1;
this.Input2 = input2;
this.InputEntity = inputAccount;

        this.InputEntityCollection = inputAccountCollection;
        this.getMetadata = function () {
return {
                boundParamter: null, // for entity action, put the entitysetname/ entitylogicalname here
parameterTypes: {
“Input1”: {
“typeName”: “Edm.String”,
structuralProperty”: 1 // Primitive Type
                    },
“Input2”: {
“typeName”: “Edm.String”,
structuralProperty”: 1 // Primitive Type
                    },
“InputEntityReference”: { // Entity Reference
“typeName”: “mscrm.account”,
structuralProperty”: 5
                    },
“InputEntity”: { // entity
“typeName”: “mscrm.account”,
“structuralProperty”: 5
                    },
“InputEntityCollection”: { // entity collection
“typeName”: “Collection(mscrm.crmbaseentity)”,
“structuralProperty”:4 // collection type
                    }
},
operationType: 0, // 0 for action, 1 for function and 2 for CRUD
operationName: “new_TestAction1”
};
};
}

Next is the code to create this request object and pass the object to the action.
ExecuteAction: function () {
debugger;
var accountReference = {
“@odata.type”: “Microsoft.Dynamics.CRM.account”,
“@account.id”: “9602CEB2-55F7-E711-A954-000D3A34A0AA”
};
var accountEntity = {
“@odata.type”: “Microsoft.Dynamics.CRM.account”,
“@account.id”: “9602CEB2-55F7-E711-A954-000D3A34A0AA”
};
var accountEntityCollection =[
{
“@odata.type”: “Microsoft.Dynamics.CRM.account”,
“@account.id”: “9602CEB2-55F7-E711-A954-000D3A34A0AA”,
“name”: “Test Account 1”
},
{
“@odata.type”: “Microsoft.Dynamics.CRM.account”,
“@account.id”: “9602CEB2-55F7-E711-A954-000D3A34A0AA”,
“name”: “Test Account 1”
}];
var requestObject = new TestAction1(“Name”, “Age”, accountReference, accountEntity, accountEntityCollection);
Xrm.WebApi.execute(requestObject).then(function (result) {
debugger;
},
function (error) {
debugger;
console.log(error.message);
});
    }

Simple isn’t it. I haven’t covered the other primitive types like – Decimal/ Int. They are pretty simple like for int, it is Edm.Int32.
Hope this helps!
-Debajit Dutta
(Dynamics MVP)
For consultation/ training visit www.xrmforyou.com or reach out to us at info@xrmforyou.com
 

7 thoughts on “Invoke an action in dynamics 365 – Xrm.WebApi with EntityReference, entity and entitycollection input parameters”

  1. Hi Debajit,
    Thank you so much for this blogpost. It helped me a lot.
    One question: Should this “@account.id”: be “accountid”: ?

    1. For non-global action (entity action), i have pointed out in the blog to set the entity logical name and entity set name.

  2. I’m very grateful that you’ve taken the time to do what Microsoft should have already done (provide working examples of this code) – you’ve already saved me hours and hours of effort; thank you.
    I do still have a problem that I cannot fix though. My bound custom Action takes a single DateTime parameter. I cannot find a format that will be accepted by the platform.
    I understand that OData requires DateTime vaues to be submitted as “Edm.DateTimeOffset”. My parameterType is therefore set as:
    “EffectiveFrom”:
    “typeName”: “Edm.DateTimeOffset”,
    “structuralProperty”: 1 // PrimitiveType
    (Braces removed as comments won’t allow it)
    I understand the required format should be a string representation of the DateTime in the format yyyyMMddThhmm:ss.sssZ. I achieve this with the native JavaScript:
    var myDateTimeParameter = new Date();
    this.EffectiveFrom = myDateTimeParameter.toISOString();
    Whenever I submit this request to the platform, I get the following error:
    “An error occurred while validating input parameters: Microsoft.OData.ODataException: Invalid JSON. The value ‘2019-04-25’ is not a valid number.”
    Have you successfully submitted a request with a DateTime parameter?

    1. Unbelievable… I’ve literally spent hours on this. Seconds after posting I had a brainwave and it seems that it works.
      When setting the the value of my parameter, it needs to be wrapped in JSON.stringify:
      this.EffectiveFrom = JSON.stringify(myDateTimeParameter.toISOString());
      Then it will work. Hopefully this helps someone!

Comments are closed.