serving the solutions day and night

Pages

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 http://makdns.blogspot.com/2012/11/crmsvcutilexe-crm-dynamics-2011-code.html (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 http://makdns.blogspot.com/2013/04/crm-developer-tool-kit.html.
<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">
  <Steps>
    <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" />
  </Steps>
</Plugin>


image

step (must be post operation to get output value)


Call your Action from your server side code
[TestMethod]
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);
    Console.Write(res["ValidContact"]);

    //Calling the Action - Way 2
    DNSEntities.edm_TestActionNameRequest()
    {
        ContactID = new EntityReference("contact", cid),
    };
    DNSEntities.edm_TestActionNameResponse res1 = ser.Execute(req1) as DNSEntities.edm_edm_TestActionNameResponse;
    Console.Write(res1["ValidContact"]);
}

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);

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

     //Parse response
     var xmlDoc = XmlHttpRequest.responseXML;
     var ret,juriname = "";
     var akeys = xmlDoc.getElementsByTagNameNS("http://schemas.datacontract.org/2004/07/System.Collections.Generic", "key")
       var avalues = xmlDoc.getElementsByTagNameNS("http://schemas.datacontract.org/2004/07/System.Collections.Generic", "value")
       if (akeys[0].firstChild.nodeValue == "AbsBall")
                        ret = avalues[0].firstChild.nodeValue;
                    else
                        ret = avalues[1].firstChild.nodeValue;

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

},
error: function (XmlHttpRequest, textStatus, error) {
   console.log(XmlHttpRequest.responseText);
}
    });
}

ResponseText
"<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><ExecuteResponse xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services"><ExecuteResult xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><a:ResponseName>edm_TestActionName</a:ResponseName><a:Results xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic"><a:KeyValuePairOfstringanyType><b:key>AbsBall</b:key><b:value i:type="c:boolean" xmlns:c="http://www.w3.org/2001/XMLSchema">true</b:value></a:KeyValuePairOfstringanyType><a:KeyValuePairOfstringanyType><b:key>JuriName</b:key><b:value i:type="c:boolean" xmlns:c="http://www.w3.org/2001/XMLSchema"></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=\"http://schemas.microsoft.com/xrm/2011/Contracts\" xmlns:b=\"http://schemas.microsoft.com/crm/2011/Contracts\">";
request += "        <a:Parameters xmlns:c=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
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=\"http://schemas.xmlsoap.org/soap/envelope/\">";
envelope += "  <s:Body>";
envelope += "    <Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
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.

Associate
Disassociate
Execute
Export
ExportAll
ExportCompressed
ExportCompressedAll
Import
ImportAll
ImportCompressedAll
ImportCompressedWithProgress
ImportWithProgress
Publish
PublishAll
RemoveProductFromKit
RetrievePersonalWall
RetrieveRecordWall
UnlockInvoicePricing
UnlockSalesOrderPricing

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: