Integrating with Microsoft CRM
- Home
- Neuron ESB
- Development
- Samples and Walkthroughs
- How To
- Integrating with Microsoft CRM
This How To will describe various Neuron CRM capabilities and will also provide guidance around some common use cases.
The actual details of each adapter’s functionality are described in detail in the Neuron help file in the Adapter section.
This How To will not focus on those details. Instead this How To’s purpose is to help you maximize your productivity when using the adapters and prevent you from hitting common pitfalls.
Concepts
Neuron provides 3 ways out of the box to communicate with Microsoft CRM
- Neuron WF Publishing Adapter – Uses MSCRM functionality in combination with either the Neuron Publishing API or WCF to send messages from CRM to external systems. This Adapter runs inside of CRM.
- Neuron CRM Subscription Adapter-This Adapter runs inside Neuron and is used to send messages into CRM.
- Service Connectors-Can be used to route messages to and from the standard MCRM Web Services which allows you to put data into CRM and get data from CRM.
It is important to note that if you require Request-Reply messaging you must go the Service Connector route.
Neuron WF Adapter
Use this adapter when you want to send messages to other systems in response to events occurring inside CRM.
The CRM WF Adapter directory is located under the Plugins subdirectory under the Neuron install directory
Ensure you choose the correct one for your platform.
You will need to use your host name and the correct crm organization name to install.
If you are running MSCRM on the same IIS server as other sites and have set up a CNAME and host headers it is strongly encouraged that you become familiar with Microsoft KB article 947423 (currently located at https://support.microsoft.com/kb/947423/).
If you should have applied the recommendations that are listed there and do not then your WF’s will never fire. This is not a Neuron specific issue but because Neuron depends on this functionality working you need to make sure this has been done if it is necessary.
After you have installed the adapter and have restarted both the Microsoft CRM Asynchronous Processing Service and IIS you are ready to publish events from crm.
Once this is done you are ready to start using the Adapter. The first step is to doing so is to create and WF by navigating to Settings Workflows inside CRM. You’ll notice that the Scope for a new workflow defaults to User. If you want a WF to affect records for all users based on changes to entities (i.e. whenever anyone does something with Contact publish) you will need to use an account with appropriate permissions for the scope.
The next step to using Neuron in the WF adapter is add a step and to choose your publishing option
Topics or Services?
You’ll notice that there are two top level options for Neuron Topics or Services.
When you choose the Topics option what happens is a Neuron Party is used to publish the Entity to Neuron using a Multicast Semantic. This means you will have full access to Neuron Processes, Connectors, and Adapters etc when choosing this option.
You should choose this option when:
- You want to send to more than one subscribing system or may have to send to more than one subscribing system in the future.
- You want to accomplish complex processing using the full capabilities of Neuron Processes
- You need to communicate over protocols other that Web Services
- You do not want your CRM developers to have to understand WCF bindings, WCF binding configurations, XSLT etc.
The other option is Services. When you choose this option you are using a WCF proxy to communicate directly to the target service. You should use this option when
- You anticipate the only action you will need to do is use a transform before sending the message directly to the web service
- You want to connect directly to the web service and do not want to utilize the pub sub system inside Neuron
- You want the lowest latency possible between CRM and the web service.
A common error when utilizing the Service Step is leaving the service as
Both options can leverage the built in ability of CRM WF to resume or be restarted in the case of error so that if for some reason either the target web service or Neuron itself is offline the update will not be lost.
Send Type
You’ll notice there are 4 send types. Which one should you use? Your first choice should likely be the Dynamic Entity send. The Dynamic Entity send produces what some would view as a less pleasing XML than the other options but it allows you to customize and edit an Entity and not have to reconfigure your workflow to pick up the changes.
The XML can be challenging for those new to XSLT. A snippet of a Dynamic Entity looks like this:
<DynamicEntity xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="https://www.w3.org/2001/XMLSchema" Name="contact">
<Properties xmlns="https://schemas.microsoft.com/crm/2006/WebServices">
<Property xsi:type="PicklistProperty" Name="customertypecode">
<Value name="Default Value">1</Value>
</Property>
<Property xsi:type="StringProperty" Name="mobilephone">
<Value>5554443333</Value>
</Property>
<Property xsi:type="CrmBooleanProperty" Name="merged">
<Value name="No">false</Value>
</Property>
<Property xsi:type="PicklistProperty" Name="territorycode">
<Value name="Default Value">1</Value>
</Property>
<Property xsi:type="PicklistProperty" Name="haschildrencode">
<Value name="Default Value">1</Value>
</Property>
<Property xsi:type="CrmDecimalProperty" Name="exchangerate">
<Value formattedvalue="1.0000000000">1.0000000000</Value>
</Property>
Despite using XSLT to extract values for transforms is straightforward and using this pattern can give you access to the values
<xsl:value-of select="//*[local-name()='Property'][@Name='{the value of the “name” attribute of the Propert you want goes here}']/*[local-name()='Value']" />
So, a simple transform might look like this for the Contact Entity to a web service that updates contact info in another system might look like this
<UpdateProfile>
<firstName>
<xsl:value-ofselect="//*[local-name()='Property'][@Name='firstname']/*[local-name()='Value']" />
</ firstName>
<lastName>
<xsl:value-ofselect="//*[local-name()='Property'][@Name='lastname']/*[local-name()='Value']" />
</lastName>
<jobTitle>
<xsl:value-ofselect="//*[local-name()='Property'][@Name='jobtitle']/*[local-name()='Value']" />
</jobTitle>
</UpdateProfile>
Of course if you use the Topics option you also have access to the Code Step for transforms so you would not have to use XSLT if you preferred not to.
Neuron CRM Subscription Adapter
The Neuron CRM Adapter was developed using the Adapter SDK. This Adapter allows sending updates to be inserted into CRM.
There is extensive documentation describing the XML required for this adapter in its help section.
Some concepts are helpful to keep in mind however. Underneath the covers this Adapter is using the CRM sdk and invoking Execute. The name of the entity you are targeting is in a property aptly named entity. The id at the same level is an id that is unique for the batch and is used for tracing, debugging in the event of an issue. As an example the id property in the SaveCrmRecord below is not the id of the entity. That is contained in the message body.
<SaveCrmRecord allowCreate="false" id="contact1" entity="contact" identityfield="contactid">
<propertyname="emailaddress1" value="first.last@domain.com" typename="String" />
<propertyname="birthdate" value="04/11/1982 12:00:00 AM" typename="CrmDateTime" />
<propertyname="firstname" value="John" typename="String" />
<propertyname="lastname" value="Smith" typename="String" />
<propertyname="donotemail" value="false" typename="CrmBoolean" />
<propertyname="contactid" value="{80C4BC51-C91E-DE11-B893-0003FF2A866D}" typename="Key" />
<propertyname="creditlimit" value="10000" typename="CrmMoney" />
<propertyname="department" value="Neudesic Sales" typename="String" />
</SaveCrmRecord>
Service Connectors
Sometimes you need a Request Reply messaging pattern with CRM. The simplest example of this is wanting to query. In order do this through Neuron you must use a Service Connector. The Service Connector can subscribe to either Neuron Generated messages or messages sent in from a Client Connector.
If you are simply using Neuron for location transparency and routing then this is straight forward in terms of messaging payload. If you desire for the user identity to propagate then you will have to make sure that Kerberos is configured correctly and you have set the proper security along with Enable Impersonation on the security tab for both the Client Connector and the service Connector:
If you do not need to propagate identity or cannot/do not have Kerberos configured correctly you will need to set the service connector to use explicit credentials unless CRM allows connections from the account Neuron is running as.
Neuron Initiated Invocation
If you are publishing to the Service Connector from an Adapter or from a Process designed to decouple your clients from CRM then you are most likely going to have to inject a CRM header.
An example of the code required to inject the header is below
string tokenHeaderName = "https://schemas.microsoft.com/crm/2007/WebServices/CrmAuthenticationToken";
string prefix = "soap_headers";
string propCheck = context.Data.GetProperty(prefix,tokenHeaderName);
string orgName = "[YOUR ORGANIZATION NAME GOES HERE]";
if(string.IsNullOrEmpty(propCheck))
{
context.Data.SetProperty(prefix,tokenHeaderName,
string.Format(@"<CrmAuthenticationToken xmlns=""https://schemas.microsoft.com/crm/2007/WebServices"">
<AuthenticationType xmlns=""https://schemas.microsoft.com/crm/2007/CoreTypes"">0</AuthenticationType><OrganizationName xmlns=""https://schemas.microsoft.com/crm/2007/CoreTypes"">{0}</OrganizationName><CallerId xmlns=""https://schemas.microsoft.com/crm/2007/CoreTypes"">00000000-0000-0000-0000-000000000000</CallerId>
</CrmAuthenticationToken>"
,orgName));
}
This code is using the Neuron ESB message properties to inject the CRM header. This property will be serialized into a SOAP Header by a Service Connector whenever
Restore Custom headers is set true
Fetch XML Encoding
If you need to use XSLT on the result of a fetch XML call it may be necessary to decode the returned XML in order to be able to apply transformations.
One of the ways to do this is to add a reference to System.Web inside a Code Step and to use the following code
string decoded = System.Web.HttpUtility.HtmlDecode(context.Data.ToString()); context.Data.FromXml(decoded);
Some characters like apostrophe may not be picked up by this method and need special handling via string.Replace