Blog Archives

CRM 4 WCF Integration

In this post i will talk about integrating the Microsoft CRM UI with backend WCF services. In the CRM SDK there is a lot of examples about creating sample SOAP requests to access the CRM SDK web services. However this involves a lot of manual work which includes generating the SOAP request message and then parsing the SOAP response message. If you are trying to retrieve and manipulate a lot of data in many forms this can be quite time consuming and difficult to maintain. One alternative is write your own custom JavaScript helpers that can simplify the process for you. However this also requires investing the time to implement the helper code. What if you want to call third party web services? This can be difficult to access using JavaScript depending on the complexity of the service definition and can have various security implicaitons.

Luckily WCF in .NET 3.5 provides the capability to expose WCF services that can be easily consumed using AJAX enabled web pages. The WCF Web Extensions architecture is based around custom bindings and behaviors that make it easy and efficient to consume backend services using Javascript. However most of this functionality is implemented using ASP.NET using the ScriptManager class. The ScriptManager on the ASP.NET page is responsible for rendering all the scripts required for the AJAX libraries to function including any proxy to WCF services. This makes the ScriptManager useless for CRM as the only supported way of customising a CRM form is by injecting Javascript on the CRM exposed events. The good news however is that with a few tweaks we can make all that functionality available on the CRM form.

This approach of being able to invoke WCF services from within the CRM UI we give us many useful features that can be used to extend CRM.

  • Implement custom WCF services that are designed to be used by the CRM UI. Thus making the least number of calls as possible and only retrieving the required data.
  • Access the return/input parameters of the CRM operations as proper JavaScript objects with no extra effort.
  • The ability to implement very complex logic in the helper service that could include talking to CRM SDK services, Third party services or databases.
  • Easy to maintain as operations can be altered/added/removed with minimal effort. There is no need to update any proxy scripts as they get generated at runtime.

The implementation consists of a custom web application deployed under the ISV directory on the CRM website. The web application will host the custom helper WCF service and provide all the scripts and customisations required to invoke the WCF service from a CRM form. The first step is to implement the WCF service. This will be implemented as a standard .NET library. I will not go into the details of the implementation of the WCF service as it is outside the scope of this post. Below is the code for the sample WCF service.

    7 namespace CRMWCFService

    8 {

    9     public class CRMService : ICRMService

   10     {

   11         public CRMEntity GetCRMData(string message)

   12         {

   13             return new CRMEntity()

   14             {

   15                 Name = “Demo “ + message,

   16                 Active = true,

   17                 Date = DateTime.Now,

   18                 User = OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name

   19             };

   20         }

   21     }

   22 }

The next step is to host the service in our custom web application. To do that add the reference to the previously created library and then create a new “Services” directory in the web application. Then add two files. The first file is “JSService.svc” which is the base endpoint address for the service. Below are the contents of the file.

    1 <%@ ServiceHost

    2     language=”C#”

    3     Debug=”true”

    4     Service=”CRMWCFService.CRMService”

    5 %>

To finish the service setup also add a web.config file to the same directory that includes the configuration for the WCF Service. The service will use windows authentication. However when you host the web application in IIS make sure you enable anonymous access on the “Services” directory to allow access to the metadata endpoint. You can also enable anonymous access on the script files to speed up loading time performance. Note the endpoint behavior that enables the endpoint to be accessible using AJAX.

   10 <configuration>

   11   <system.serviceModel>

   12     <bindings>

   13       <webHttpBinding>

   14         <bindingname=Secure>

   15           <securitymode=TransportCredentialOnly>

   16             <transportclientCredentialType=Windows />

   17           </security>

   18         </binding>

   19       </webHttpBinding>

   20     </bindings>

   21     <services>

   22       <servicebehaviorConfiguration=CRMServiceBehaviorname=CRMWCFService.CRMService>

   23         <endpointaddress=“”binding=webHttpBindingbindingConfiguration=SecurebehaviorConfiguration=AjaxBehavior

   24           name=Servicecontract=CRMWCFService.ICRMService />

   25         <endpointaddress=mexbinding=mexHttpBindingname=Meta

   26           contract=IMetadataExchange />

   27       </service>

   28     </services>

   29     <behaviors>

   30       <endpointBehaviors>

   31         <behaviorname=AjaxBehavior>

   32           <enableWebScript/>

   33         </behavior>

   34       </endpointBehaviors>

   35       <serviceBehaviors>

   36         <behaviorname=CRMServiceBehavior>

   37           <serviceMetadatahttpGetEnabled=true />

   38           <serviceDebugincludeExceptionDetailInFaults=true />

   39         </behavior>

   40       </serviceBehaviors>

   41     </behaviors>

   42   </system.serviceModel>

   43 </configuration>

The next step is to create a script called “EntityOnLoad.js” that will loaded into the CRM form. The script will first load the Microsoft AJAX library that would otherwise have been available on the client using the ASP.NET ScriptManager. To create this file you can create a test ASP.NET page as demonstrated in the sample download at the end of this post. In the test page add reference to the WCF service in the ScriptManager. Fire up the page and view the source. In there you will see references to various script files and one of them is the Microsoft AJAX library that you can save and reuse. This file should only be updated if you install a new version of .NET framework or apply a service pack. The next step is to load the JavaScript proxy for the service. WCF provide these files as part of the metadata for a web enabled WCF service. So all we need to do is link to the WCF JS metadata URL. The last step is to invoke the WCF Service asynchronously by passing a return delegate. The code below demonstrates these step.

   13 if (!window.EntityOnLoad)

   14 {

   15     window.EntityOnLoad = {};

   16 }

   17

   18 EntityOnLoad.Load = function() {

   19

   20     //Load Microsoft Ajax Library

   21

   22     var oXML = new XMLHttpRequest();

   23     oXML.open(‘GET’, ‘/ISV/CRMWCFWeb/MicrosoftAjax.js’, false);

   24     oXML.send();

   25     eval(oXML.responseText);

   26

   27     //Load Service Proxy

   28

   29     oXML = new XMLHttpRequest();

   30     oXML.open(‘GET’, ‘/ISV/CRMWCFWeb/Services/JSService.svc/js’, false);

   31     oXML.send();

   32     eval(oXML.responseText);

   33

   34     CRMWCFService.CRMService.GetCRMData(“CRM “ + crmForm.ObjectTypeName, onComplete, onError);

   35 }

   36

   37 function onComplete(result) {

   38     var message = “Name: “ + result.Name + “n”;

   39     message += “Active: “ + result.Active + “n”;

   40     message += “Date: “ + result.Date + “n”;

   41     message += “User: “ + result.User + “n”;

   42     alert(message);

   43 }

   44

   45 function onError(error) {

   46     alert(error.get_message());

   47 }

Finally the last and easiest step is to load the script and execute it from the CRM UI. For demonstration purposes i will just call the service on the load event. However you can call this code from anywhere you like. The code below needs to be added to “OnLoad” event for the CRM form. If everything is step up properly you should see a popup when you open the CRM form.

    1 try {

    2     oXML = new XMLHttpRequest();

    3     oXML.open(‘GET’, ‘/ISV/CRMWCFWeb/EntityOnLoad.js’, false);

    4     oXML.send();

    5     eval(oXML.responseText);

    6

    7     EntityOnLoad.Load();

    8 }

    9 catch (ex) {

   10     alert(‘Failed to load :’ + ex.description);

   11     window.close();

   12 }

As you can see once everything is setup, making calls to the WCF service is just a matter of calling a method and processing the response. I have created a sample that includes all the required files and test pages. The sample demonstrates the concepts in this post and provides you with a working example. However note that if you decide to run the sample locally in visual studio you will have to configure the web application to run under IIS instead of the visual studio built-in web server. Otherwise you will get an error indicating that Windows Authentication is not supported. Hope you find this post useful.

You can download the sample code from here.