Silverlight 2 and CRM


Q: Is there a way to directly call CRM 4 from Silverlight 2 managed code using the auto-generated proxy?


A: Yes 🙂 with a small workaround that will be available with SL2 RTM.


I finally had a bit of time to spend on a matter that personally bothered me.  During TechEd 2008 I demonstrated how managed code could talk to CRM using an intermediary WCF proxy… why did I have to use the WCF proxy? Because the CRM Web Service didn’t seem to play well with the proxy that SL2 auto-generates. Things worked but having that piece of code in the middle (the proxy) didn’t seem quite right (although I can tell you that there are very valid scenarios in which you would definitively like to have a proxy, for example if you are aggregating data from different sources).  Of course you could talk to CRM directly if you build your own proxy (basically handcrafting the SOAP requests using POX) or use an existing one (This book actually has nice sample code that you can reuse). Anyway, I didn’t post the TechEd sample because I didn’t feel comfortable with the proxy pattern, especially because the sample didn’t use the proxy other than to talk to CRM. 


Sniffing the HTTP communication between the auto-generated SL2 proxy and CRM it seemed that the problem was the CRM authentication token wasn’t being passed from SL2 to CRM…. but how to test my theory?  Turns out that on the Beta 2 bits of SL2 injecting a SOAP header into the outgoing request was not a trivial task (you had to extend the channel and do a bunch of code to merely inject a couple of lines into the outgoing request).  I contacted the Silverlight team and they informed me that injecting SOAP headers was going to get a lot easier with post beta 2 (closer to RTM) bits of SL2…a couple of weeks back I got an email with sample code that demonstrated how to inject the SOAP headers and guess what?


Yes!… it worked J. My theory was correct and after injecting the authentication header I was able to use the auto-generated proxies in SL2 and talk directly to CRM.  


It was a bit tricky at first because I had to properly encode the authentication token but I was finally able to directly call CRM from SL2 managed code; I was really happy to see the “Test Account” text appearing on the screen (yes, I was retrieving the name of an account).


So great you say; now give me the code, right?  Well, unfortunately I can’t do that since I’m using a set of SL2 bits that hasn’t been released yet but I have the sense that SL2 will RTM pretty soon and when that happens I’ll validate once again that the code works and post it on the web (the actual VS project). Please don’t ask me about SL2 RTM date or anything like that because honestly I don’t know.


However I see no harm in posting the key piece of the puzzle … and if for some reason you do have access to SL2 latest bits you will be able to try this out (it may be challenging since you do have to figure out some missing instructions in order for this to work but hey!,  you are smart right J ).  When I post the complete project it will have all the code and all the detailed instructions.


******UPDATE*******:  See this post, there is a link there to the code.






void Page_Loaded(object sender, RoutedEventArgs e)


        {


 


            CrmServiceSoapClient crmService = new CrmServiceSoapClient();


 


 


            crmService.RetrieveCompleted += new EventHandler<CRMSilverlightDirect.CrmSdk.RetrieveCompletedEventArgs>(crmService_RetrieveCompleted);


 


            // Create the column set object that indicates the fields to be retrieved.


            ColumnSet cols = new ColumnSet();


 


            // Set the properties of the column set.


            cols.Attributes = new string[] { “name” };


            using (new OperationContextScope((IContextChannel)crmService.InnerChannel))


            {


                //This is the KEY part… we inject the CRM Authentication header


                //The Xml formater is just to prevent some characters from being encoded (otherwise CRM can’t parse the authentication token properly)


                MessageHeader header = MessageHeader.CreateHeader(“CrmAuthenticationToken”, “http://schemas.microsoft.com/crm/2007/WebServices”, “”, new MyCrmAuthenticationTokenSerializer(0, “crm5Org”, null));


                // Insert SOAP header


                OperationContext.Current.OutgoingMessageHeaders.Add(header);


 


                crmService.RetrieveAsync(“account”, new Guid(“1EB30C87-EA80-DD11-AE35-00155DA20A01”), cols);


            }


        }


 

Comments (10)

  1. Tinus says:

    Hi,

    Great post. Are you still planning on posting the code? Would be great help!

    Cheers,

    Tinus

  2. Tinus,

    Yes, the code is coming :).  SL2 RTWed last week and we were just double checking some hiccups.  I’ll do my best to post a very simple code sample in the upcoming days.

  3. lnxpenguin4ever says:

    Dude…you are my hero!  I’ve been trying to integrate Silverlight 2 with CRM since Beta 1.  This article is the first one I’ve seen in about a year that actually talks about doing this!

    I think Silverlight + CRM is going to be a game-changer. 🙂

  4. Silverstarter says:

    Im very happy that theres some one who bothers about this connection, im trying to dig trough other examples like the CRMSL2B2 from microsoft but it seems to require a little too much of a nerd for me to understand 😉

    are there any news on your project?

  5. Ok, so here it is ( download ); I finally had the chance to finish this sample and put it in a form that

  6. Ok, so here it is ( download ); I finally had the chance to finish this sample and put it in a form that

  7. Anthony says:

    Hi.  Great post.  Loaded the sample code, updated url & organisation, & web service reference to my environment (I am using a VPC Win 2003 image by the way).  Everything worked perfectly.  I modified slightly adding a data grid control for the returned result – all working great still.  Then afer restarting my VPC I got an error in method "public CrmSilverlightDirect.CrmSdk.Response EndExecute(System.IAsyncResult result)" – The error is "The remote server returned an error: NotFound".  I ran Fiddler to try and see what was happening, and then it worked ok.  It now seems I can only get it to work if I am running Fiddler.  I am trying to run it using the VS Development Server.  Is this something to do with going cross domains? My CRM system is on port 5555-Dev Server is random high number.  If you could help I would be extemely grateful.

  8. Great sample, some months ago i have strugled to get it to work. Your sample helped me allot – thanks 😉

  9. Kandasamyg says:

    I am also trying to wet my hands with this demo projcet (CRMSL2B2 from microsoft ). But i am sensing The below mentiond method throws this exception

    "The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element"

    public CRMSLParts.CrmSdk.Response EndExecute(System.IAsyncResult result) {

                   object[] _args = new object[0];

                   CRMSLParts.CrmSdk.Response _result = ((CRMSLParts.CrmSdk.Response)(base.EndInvoke("Execute", _args, result)));

                   return _result;

               }

    Could you please tell me that which web.config file needs to update?

    Note: I tried updating both crm iis server web.config and my silvelight app's side( Maxreturnlength).

    But still i get the same error. Your timely help would be highly appreciated.

    THanks

    Kandasamy