Wednesday, 12 April 2017

Communicate with WCF web service from JavaScript using CRM actions

For one of our clients’ we needed to communicate to a WCF service using JQuery/Ajax from CRM.
CRM is a hosted version, uses IFD and the WCF service which communicates to and from CRM uses http protocol.
When we tried to access the WCF web service method directly from JQuery Ajax call, it was throwing a  cross domain error. CRM Actions came to the rescue this time. We would like to share the approach we have taken to call WCF from CRM javascript.
Action is used to trigger the Plug-in, which then communicates with the webservice.  As the webservice is being called from the server side code, there is no issue of cross domain here. To trigger the CRM action we needed to create the request and process that request. Action input and output parameter are used to set the values in CRM plug-in.
Image01
Below is a step by step process on how to implement this:
We will take a scenario here where CRM Contact stores the Employee Id, but the employee details have to be fetched from the 3rd party application using a webservice exposed by this 3rd party application.
So we pass the input parameter ‘EmpId’ (Employee Id) from javascript to the CRM Action. This Action along with plug-in process the request, communicates with the WCF and then returns the output parameter to the javascript. Finally using the javascript we store/update the value in CRM.
  • To create the CRM action navigate to Settings–>Processes–>Add New. Select the Category as ‘Action’ in the Create Process window.     Image02
  • Add input and output arguments
Image03
  • Create a new Javascript file and use the Javascript method given below
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
function ExecuteActionCreateProject(empId,  entityId, entityName, requestName) {
//Creating the request XML for calling the Action
var requestXML = ""
requestXML += "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">";
requestXML += "  <s:Body>";
requestXML += "      <request xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
requestXML += "        <a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
requestXML += "          <a:KeyValuePairOfstringanyType>";
requestXML += "            <b:key>Target</b:key>";
requestXML += "            <b:value i:type=\"a:EntityReference\">";
requestXML += "              <a:Id>" + entityId + "</a:Id>";
requestXML += "              <a:LogicalName>" + entityName + "</a:LogicalName>";
requestXML += "              <a:Name i:nil=\"true\" />";
requestXML += "            </b:value>";
requestXML += "          </a:KeyValuePairOfstringanyType>";
requestXML += "          <a:KeyValuePairOfstringanyType>";
requestXML += "            <b:key>EmpId</b:key>";
requestXML += "            <b:value i:type=\"c:string\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + empId + "</b:value>";
requestXML += "          </a:KeyValuePairOfstringanyType>";
requestXML += "        </a:Parameters>";
requestXML += "        <a:RequestId i:nil=\"true\" />";
requestXML += "        <a:RequestName>" + requestName + "</a:RequestName>";
requestXML += "      </request>";
requestXML += "    </Execute>";
requestXML += "  </s:Body>";
requestXML += "</s:Envelope>";
var req = new XMLHttpRequest();
req.open(true, GetClientUrl(), false);
req.setRequestHeader("Accept", "application/xml, text/xml, */*");
req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
req.send(requestXML);
//Get the Resonse from the CRM Execute method
var response = xmlToObject(req);
var empFName = '', empLName = '';
if (response != null && response['EmpFName'] != null) {
empFName = response['EmpFName'];
empLName = response['EmpLName'];
}
Xrm.Page.getAttribute('new_empFName').setValue(empFName);
Xrm.Page.getAttribute('new _empLName').setValue(empLName);
}
function GetClientUrl() {
if (typeof Xrm.Page.context == "object") {
clientUrl = Xrm.Page.context.getClientUrl();
}
var ServicePath = "/XRMServices/2011/Organization.svc/web";
return clientUrl + ServicePath;
}
function xmlToObject(req) {
var response = {};
var xmlResponse = req.responseXML.documentElement;
var fullNodeList = xmlResponse.getElementsByTagName("a:KeyValuePairOfstringanyType");
if (fullNodeList != null) {
for (var i = 0; i < fullNodeList.length; i++) {
if (fullNodeList[i] != null && fullNodeList[i].childNodes != null && fullNodeList[i].childNodes.length >= 2 &&
fullNodeList[i].childNodes[0].textContent != null && fullNodeList[i].childNodes[0].textContent != null) {
response[fullNodeList[i].childNodes[0].textContent] = fullNodeList[i].childNodes[1].textContent;
}
}
}
return response;
}
Calling the WCF web service method from CRM plugin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
int pmtRefNo = 0;
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is EntityReference)
{
try
{
EntityReference entityObj = (EntityReference)context.InputParameters["Target"];
string EmpId = (String)context.InputParameters["empId"];
EmployeeDetails empDetails = CallWebserviceMethods().GetEmployeeDtls(empId);
if (empDetails != null)
{
context.OutputParameters["EmpFName"] = empDetails.EmpFName;
context.OutputParameters["EmpLName"] = empDetails.EmpLName;
}
}
catch (Exception ex)
{
WriteLocalLog(ex, "Execute");
}
}
}
/// <summary>
/// Method to call Webservice.
/// </summary>
/// <returns></returns>
private ICRMService CallWebserviceMethods()
{
BasicHttpBinding myBinding = new BasicHttpBinding();
myBinding.Name = "BasicHttpBinding_ICRMService";
myBinding.Security.Mode = BasicHttpSecurityMode.None;
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
myBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
myBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
EndpointAddress endPointAddress = new EndpointAddress("http://xxxxx/CRMService.svc");
_factory = new ChannelFactory<ICRMService>(myBinding, endPointAddress);
ICRMService channel = _factory.CreateChannel();
return channel;


Powered by : http://osmosys.asia/

No comments:

Post a Comment

Voice of the Customer (VOC) – Dynamics 365 CRM

Tags:   Dynamics 365   Dynamics CRM   feedback   survey   VOC   Voice of customer Introduction To Voice of the Customer For any bus...