serving the solutions day and night


Tuesday, March 1, 2016

Dynamics CRM Action

CRM Action is a process that allows a user to create it and add custom Workflow, but Action is only be able to be called or triggered by client (Javascript) or server code (C#).

Actions can be defined for an entity or none (Global entity).

Custom Action can be used as Custom Message or Event Handle and can be registered by using Plugin Registration Tool.

Example, storing config parameters (like server url), custom error message, used for complex business code, single point of integration for third party systems.

Create an Action without no steps, message name is edm_TestActionName, entity is none, passing one input ContactID (reference) & one output ValidContact (boolean) parameters. Activate it

Generate an Early Bound Class to get your action in your class library, refer this blog (parameter /generateActions)

Create a Plugin Class, compile & deploy

namespace DNS.VM.Plugins
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using DNS.Crm.Entities;
    using DNSBL = DNS.Crm.BusinessLogic;
    using Microsoft.Xrm.Sdk;
    using Microsoft.Xrm.Sdk.Query;
    using Microsoft.Crm.Sdk.Messages;
    using System.Globalization;

    public class edm_TestActionName : IPlugin
        public void Execute(IServiceProvider serviceProvider)
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
            EntityReference ContactRef = context.InputParameters["ContactID"] as EntityReference;
            bool abOut= DNSBL.ContactBLL.ReturnedContact(service, ContactRef.Id);
            context.OutputParameters["ValidContact"] = abOut;

i used CRM DEveloper Tool kit to deploy & register, refer the blog
<Plugin Description="Plug-in to edm_TestActionName" FriendlyName="edm_TestActionName" Name="DNS.VM.Plugins.edm_TestActionName" Id="d4837064-d2df-e511-80ec-0050568c3250" TypeName="DNS.VM.Plugins.edm_TestActionName">
    <clear />
    <Step CustomConfiguration="" Name="PreValidate" Description="Test Action Name" Id="6f7ec7ec-d3df-e511-80ec-0050568c3250" MessageName="edm_TestActionName" Mode="Synchronous" PrimaryEntityName="" Rank="1" SecureConfiguration="" Stage="PostOutsideTransaction" SupportedDeployment="ServerOnly" />


step (must be post operation to get output value)

Call your Action from your server side code
public void CancelAbsenteeApplication()
    //Testing business method
    var ser = new DNSEntities.CrmUtilities().CrmService;
    DNSEntities.XrmServiceContext con = new DNSEntities.XrmServiceContext(ser);
    Guid cid = new Guid("B0197288-16B0-E511-80EA-0050568C2FC0");
    bool rc = DNSBL.ContactBLL.ReturnedContact(service, cid);

    //Calling the Action - Way 1
    OrganizationRequest req = new OrganizationRequest("edm_TestActionName");
    req["ContactID"] = new EntityReference("contact", cid);
    OrganizationResponse res = ser.Execute(req);

    //Calling the Action - Way 2
        ContactID = new EntityReference("contact", cid),
    DNSEntities.edm_TestActionNameResponse res1 = ser.Execute(req1) as DNSEntities.edm_edm_TestActionNameResponse;

Call your Action from your client side code
ffunction CAllCRMAction(cid)
    var uniqueName = "edm_TestActionName";
    var keyValue = EntityReferenceKeyValue('ContactID', "contact", voterid);
    var request = GenerateRequest('', keyValue, uniqueName);
    var requestXML = GenerateEnvelope(request);

type: 'POST',
async: true,
url: CommonOperations.GetServerWebUrl(),
contentType: 'text/xml; charset=utf-8',
headers: {
   SOAPAction: CommonOperations.CRMSOAPActionURL
data: requestXML,
success: function (data, textStatus, XmlHttpRequest) {

     //Parse response
     var xmlDoc = XmlHttpRequest.responseXML;
     var ret,juriname = "";
     var akeys = xmlDoc.getElementsByTagNameNS("", "key")
       var avalues = xmlDoc.getElementsByTagNameNS("", "value")
       if (akeys[0].firstChild.nodeValue == "AbsBall")
                        ret = avalues[0].firstChild.nodeValue;
                        ret = avalues[1].firstChild.nodeValue;

                    if (ret != undefined && ret == "true") {
                        if (akeys[0].firstChild.nodeValue == "JuriName")
                            juriname = avalues[0].firstChild.nodeValue;
                            juriname = avalues[1].firstChild.nodeValue;
                        if (juriname != undefined) //some code here

error: function (XmlHttpRequest, textStatus, error) {

"<s:Envelope xmlns:s=""><s:Body><ExecuteResponse xmlns=""><ExecuteResult xmlns:a="" xmlns:i=""><a:ResponseName>edm_TestActionName</a:ResponseName><a:Results xmlns:b=""><a:KeyValuePairOfstringanyType><b:key>AbsBall</b:key><b:value i:type="c:boolean" xmlns:c="">true</b:value></a:KeyValuePairOfstringanyType><a:KeyValuePairOfstringanyType><b:key>JuriName</b:key><b:value i:type="c:boolean" xmlns:c=""></b:value></a:KeyValuePairOfstringanyType></a:Results></ExecuteResult></ExecuteResponse></s:Body></s:Envelope>"

Generate soap Key Value Pair xml
key - key of the tag value
entityname  - name of the entity
id - id of the key
EntityReferenceKeyValue: function (key, entityname, id) {
var kv = "<a:KeyValuePairOfstringanyType>";
kv += "     <c:key>" + key + "</c:key>";
kv += "     <c:value i:type=\"a:EntityReference\">";
kv += "         <a:Id>" + id + "</a:Id>";
kv += "         <a:LogicalName>" + entityname + "</a:LogicalName>";
kv += "         <a:Name i:nil=\"true\" />";
kv += "     </c:value>";
kv += "</a:KeyValuePairOfstringanyType>";
return kv;

Generae soap execute body tag request
requesttype - type of the request
keyvalue - key value pair xml
requestname - name of the request
GenerateRequest: function (requesttype, keyvalue, requestname) {
var request = "";
request += "      <request ";
if (requesttype.length >0)
   request += "      i:type=\"b:" + requesttype + "\" ";
request += "       xmlns:a=\"\" xmlns:b=\"\">";
request += "        <a:Parameters xmlns:c=\"\">";
request += keyvalue;
request += "        </a:Parameters>";
request += "        <a:RequestId i:nil=\"true\" />";
request += "        <a:RequestName>" + requestname + "</a:RequestName>";
request += "      </request>";
return request;

Generate soap envelope
request - body of the execute tag
GenerateEnvelope: function (request) {
var envelope = "";
envelope += "<s:Envelope xmlns:s=\"\">";
envelope += "  <s:Body>";
envelope += "    <Execute xmlns=\"\" xmlns:i=\"\">";
envelope += request;
envelope += "    </Execute>";
envelope += "  </s:Body>";
envelope += "</s:Envelope>";
return envelope;


Create an Action with steps, no plugin registation.

Create plug-in for message with no primary entity

When create plug-in using developer toolkit, you need to first select the primary entity for the message. There are 19 messages with no primary entity associated, which are listed below.


base.RegisteredEvents.Add(new Tuple<int, string, string, Action<LocalPluginContext>>(10, "Associate", "", new Action<LocalPluginContext>(ExecuteCusotmMethod)));

make sure that, your Plugin.cs  public void Execute(IServiceProvider serviceProvider) method should be  comment the below line
(string.IsNullOrWhiteSpace(a.Item3) ? true : a.Item3 == localcontext.PluginExecutionContext.PrimaryEntityName)), other wise your 'ExecuteCusotmMethod' method won't invoke.

No comments: