WCF & Microsoft CRM don't really like each other
Last week I spent about half a day trying to get WCF to reliabely work against Microsoft CRM web services.
I had plenty of trouble just getting the authentication to work, which I blame solely on my lack of experience in configuring WCF. The problem is that it is literally four lines of code in ASMX, and configuration + code in WCF, which you have to get just right. A big issue there was that authentication failure in the CRM services (ASMX, basically), will return an HTML page explaining the problem, and WCF was willing to give me just the first 1024 bytes of it.
Resorting to black magic hackery to get the real error message is nasty, I am not sure what to blame here, but I would say that WCF is to blame here for not showing the full error message even in the trace logs.
My current problem with this is that the response from the CRM looks something like this:
<RetrieveResult xmlns="http://schemas.microsoft.com/crm/2006/WebServices" xsi:type="account">
<owningbusinessunit>{50C57583-5F04-DC11-AF65-000C29955492}</owningbusinessunit>
<ownerid name="Oren Eini" dsc="0" type="systemuser">{48D20A98-5F04-DC11-AF65-000C29955492}</ownerid>
<name>oren eini2</name>
<accountid>{8A1BBC3C-C44B-DC11-B6EF-000C292DA987}</accountid>
</RetrieveResult>
But WCF will return to me an object with all the fields set to null. The problem is that the result message has a lot more properties, and therefor, tags in it. The CRM web service appernatly pick and choose what it will send, and doesn't bother to send empty tags for null proeprties. In the above message, the account entity has ~175 properties, so that is somewhat understandable. The problem is that there is no easy way to make WCF understand that.
After running svcutil over the wsdl, I got a C# file that was 2MB (!!) in size, so manual intervention is out, and there seems to be no easy way to do globally. Playing with the options of svcutil also shows that WCF really doesn't like that WSDL (in fact, it refused to generate DataContracts, instead relying on XML Serialization).
Again, I am not really a WCF expert, but from my experiments, that may be possible, but it is complex, non-DRY, and not worth the trouble. I am using ASMX services now, which just works.
Comments
Hmm I'm not sure, but I know the Microsoft CRM webservices are very complex. They are so complex that the Microsoft Biztalk Webservices adapter cannot handle the CRM Webservices. So for this problem they build a custom CRM Adapter.
In the past I've used the CRM Webservices a lot. You have to know there's a lot possible, but also remember that not everything works the way you expect them to work. There is a lot of information in the CRM SDK. If I'm right there is a possibility to use only the collumns you need as a result.
I think you can use the ColumnSet property from RetrieveRequest to lessen the collumns returned.
It's not surprising; in a way. The reason svcutil will use XmlSerializer instead of DataContracts is because the latter don't support xml attributes; as you can see your sample XML message is full of them :)
Also, the other problem is that the CRM services are pretty generic; in fact, at least one of them is almost sql-like.
As for the error problem, might be (though I haven't tried it) that you need to increase the MaxFaultSize; see http://blogs.msdn.com/drnick/archive/2007/08/07/increasing-the-maximum-fault-size.aspx
As far as WCF goes the product had a great vision, But I really dont know how much of it translated really into their implementation. If at all one thing that drives me crazy (about WCF), It is the WCF error reporting. Its awesome :-)
Sendhil
Comment preview