The project that I am on ran into a critical and somewhat embarrassing situation this past week. As we moved from a single node project environment into a multi-node test environment we discovered that the Dynamics 4.0 Adapter cannot be installed on multiple BizTalk Servers in the same group. Yes – you read that correctly. I have never heard of this kind of limitation and struggle with the idea the adapter was actually made available without this feature. You can read more about this limitation in the FAQ section here.
With this in mind, we needed to quickly make a 180 degree turn. I had heard of other people calling the ASMX CRM Web Services from BizTalk via WCF Adapter. The process of consuming these ASMX services is much like consuming any other Web Service. That is until you start your application and get the dreaded 401 Unauthorized error.
System.ServiceModel.Security.MessageSecurityException: The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate,NTLM'. ---> System.Net.WebException: The remote server returned an error: (401) Unauthorized
This seems like a pretty common error within the BizTalk and CRM forums. However, I was not able find any resolutions to the issue. It wasn’t until I started stepping through a .NET SDK sample that I realized that I was missing something and that was a required SOAP header. For your convenience I have built an end to end sample that will walk through creating a Lead within a Dynamics 4.0 system. Keep an eye open for the Message Assignment shape where I assign this header.
- Once we have created a BizTalk project we need to “Add Generated Items” and then select “Consume WCF Service”
- Even though Dynamics 4.0 still uses ASMX style Web Services we can select “Metadata Exchange (MEX) endpoint.
- Enter the location of your CRM Web Service i.e. http://server/MSCrmServices/2007/CrmService.asmx and click on the “Get” button.
- Once the WSDL definition has been loaded, click the “Next” button to continue.
- Click “Import” to create your schemas and sample Orchestration.
- You should find that the following artifacts have been added to your BizTalk Solution.
- Our “main” schema is called CrmService_schemas_microsoft_com_crm_2007_WebServices.xsd. Within this schema you will find all of the available Actions (Create/Update/Delete/Fetch etc) and the related entities (both custom and out of box). In this scenario we are going to create a “Lead” within our CRM system. So we can find the “Create” node and then scroll down and find the “Lead” entity.
- To keep things simple, I have created a little helper message that I will use in a Map to create an instance of this CRM Create message.
- Inside my map, I will simply map from this helper message to the actual CRM Request.
- With the building blocks in place, the next step was to update the Orchestration that was generated for us. Pretty standard stuff going on here. We want to receive an instance of our “helper” message, transform it, send the request to CRM and then write the response to disk.
- When we generated our CRM schemas, BizTalk also created a Port Type called “CrmServiceSoap” that contains all of the available operations including “Create”.
- Earlier in this post I mentioned that we need to set a SOAP header on the CRM Request message. In order to do this we want to add a Message Assignment shape after our Transformation shape.
- Within this shape we want to set the following:
msgCreateCustomer (WCF.OutboundCustomHeaders) = "<headers><CrmAuthenticationToken xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\"><AuthenticationType xmlns=\"http://schemas.microsoft.com/crm/2007/CoreTypes\">0</AuthenticationType><OrganizationName xmlns=\"http://schemas.microsoft.com/crm/2007/CoreTypes\">YourOrganization</OrganizationName><CallerId xmlns=\"http://schemas.microsoft.com/crm/2007/CoreTypes\">00000000-0000-0000-0000-000000000000</CallerId></CrmAuthenticationToken></headers>";
- The two important settings are the “AuthenticationType” and the “OrganizationName” properties. The Authentication property can take one of three values:
- 0 – AD
- 1 – Passport
- 2 – Internet Facing Deployment
- Since this is an on-premise installation we will go with 0.
- The “OrganizationName” property becomes extremely important in multi-tenant configurations where you may have multiple organizations or departments sharing a CRM implementation. Since we only have 1 organization in our deployment it is safe to just set our default value.
- It is now time to deploy and configure the BizTalk application.
- When BizTalk generated our CRM schemas and sample Orchestration, it also generated a Binding file. When we import the binding file we will discover that two send ports have been created. The first is a basicHttpBinding and the second send port uses a Custom Adapter with a Custom binding. What is the difference? Really it comes down to some addition security configuration that is available with the Custom adapter.
- Using these binding as is didn’t work for me. I needed to change the WCF-Custom Adapter to use the basicHttpBinding. I also had to make a few Security related changes including setting the Security “mode” was set to “TransportCredentialOnly”
- I also needed to set the “clientCredentialType” to “Windows”
- I wasn’t quite done here. I also need to add an Endpoint Behavior. In this case it was a “clientCredentials” behavior. Within this behavior, I set “Windows” - “allowedImpersonation” = “Impersonation”
- At this point, I am ready to configure the rest of the application and start it. Once started, I can process my sample helper message.
- Within my sample file, I have provided the following information. Once processed by BizTalk, I expect this Lead to be created within our CRM system and the CRM response to be send to disk.
- The response from CRM is a GUID.
- Once we launch the Dynamics CRM GUI, I am able to find my Barry Sanders record.
If you have high-availability requirements then I highly recommend abandoning the Dynamics CRM 4.0 adapter. Currently, and I am not sure if there are any plans, CRM 2011 does not have an adapter so now is as good as time as any to make the move. You can read more about CRM 2011 integration on Richard Seroter’s blog. Also look for a chapter on CRM 2011 integration in our upcoming book.