BUTTON(RIBBON) TO CALL PLUGIN (PASS PARAMETERS AND RECEIVE RESULTS)

At some point on the roadmap of every Dynamics 365 (CRM) developer’s life, one must have wished to press a button to call a Plugin.
A combination of Custom Actions introduced in CRM 2013 and webapi introduced in CRM 2016 made this wish very easy. Developers have used different techniques to achieve the same goal e.g. creating records of dummy enttities or updating dummy fields of an entity to call plugins.
There is a smarter way to do so using Custom Actions and here is how we can do it:
Our solution consists of 4 main parts:

1. A CRM custom action with input/output parameters (it can be bound(on an entity) or unbound(global) depending on your requirements)
2. A plugin registered on the custom action (this will perform the task and will set the outpur parameter with results)
3. Script under the button: this will use webapi to call custom action sending input parameters if necessary and will receive the results as output paramters
4. Ribbon button to call the javascript function

Process:
User presses a button on a form which fires a javascript function. JS function uses webapi to call the Custom Action and passes input parameters e.g. record’s guid. Plugin registered on this custom action gets fired as soon the custom action runs. Plugin gets input parameters and perform actions and finally set the output parameters to be returned. JS function gets the results from the output parameters set by plugin after the plugin finishes processing.

Here is a Sample Javascript function which calls custom action “val_CASCA” passing input parameter “InParameter1” and gets results in output parameter “OutParameter1” set by plugin after processing.

function CallCASCE() {
   var Id = Xrm.Page.data.entity.getId().replace('{', '').replace('}', '');
   var serverURL = Xrm.Page.context.getClientUrl();    
   var data = {
       "InParameter1": Id
   };
   var req = new XMLHttpRequest();
   // specify name of the entity, record id and name of the action in the Wen API Url
   req.open("POST", serverURL + "/api/data/v8.2/val_scas(" + Id + ")/Microsoft.Dynamics.CRM.val_CASCA", false);
   req.setRequestHeader("Accept", "application/json");
   req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
   req.setRequestHeader("OData-MaxVersion", "4.0");
   req.setRequestHeader("OData-Version", "4.0");
   req.onreadystatechange = function () {
       if (this.readyState == 4 /* complete */) {
           req.onreadystatechange = null;
           if (this.status == 200) {
               var result = JSON.parse(this.response);
               alert(result.OutParameter1);
           } else {
               var error = JSON.parse(this.response).error;
               alert(error.message);
           }
       }
   };
   // send the request with the data for the input parameter
   req.send(window.JSON.stringify(data));
}


Here is the sample Custom Action "val_CASCA" which is bound to custom entity "SCA" have one imput parameter and one output parameter of types string.


Finally the plugin registerd on this custom action.

public void Execute(IServiceProvider serviceProvider)
{

InitializeService(serviceProvider);

string results = string.Empty;
if ((context.InputParameters["Target"] is EntityReference)) { results += "InputParamters[Target] is entityreference"; }
try {

var inParam1 = context.InputParameters["InParameter1"];
if (inParam1.GetType() == typeof(string))
{
results +=" Input parameter sent from script is of type string:"+ inParam1.ToString();
}
context.OutputParameters["OutParameter1"] = results;

}
catch (Exception ex)

{
throw new InvalidPluginExecutionException("Error occured in [CustomActionPlugin]:" + ex.Message, ex);
}

}

Note: Plugin must be registered on Post operation, otherwise we will not get the parameters passed. Both webapi call and plugin are synchronous to acheive realtime results. We can show a modal popup (processing…) mens webapi requies is processing i.e. plugin is running.

As we can see that in case of bound custom actions we even get the entityreference as target input parameter. we get the InParameter1 set in javascript while calling customAction, perform operations and return the results in output parameter.

Here is a screenshot of the button(CallActionPlugin) and its results in alertbox sent from plugin.

Hope it will help specially new developers 🙂