web
You’re offline. This is a read only version of the page.
close
Skip to main content
Community site session details

Community site session details

Session Id :
Microsoft Dynamics CRM (Archived)

Problem sending early bound entities across WCF (CRM 2011)

(0) ShareShare
ReportReport
Posted on by 90

Hi all

We recently installed CRM 2011 and I'm doing some proof of concept work with WCF. I've generated the early bound entity classes using CrmSvcUtil.exe and I've created a solution with two very basic  projects - a WCF service and a console app acting as the client. The service simply  retrieves a Contact entity and sends it back to the client across WCF - this is working fine.

However when I try to return the Contact *plus* related entities (e.g. Appointments), I get this exception logged on the WCF service side:

There was an error while trying to serialize parameter http://tempuri.org/:GetContactResult. The InnerException message was 'Type 'CheshireSS.MicrosoftCrm2011.Services.Appointment' with data contract name 'Appointment:http://schemas.datacontract.org/2004/07/CheshireSS.MicrosoftCrm2011.Services' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'.

(For info, "CheshireSS.MicrosoftCrm2011.Services" is the namespace specified on the CrmSvcUtil command line, used in the generated .cs file containing the entity classes).

This is the code in my WCF service operation:

                CrmDataContext dc = new CrmDataContext("Xrm");
                Contact contact = (from c in dc.ContactSet .....etc.....
                Relationship rel = new Relationship("Contact_Appointments");
                dc.LoadProperty(contact, rel);
                return contact;

My solution actually has a third "service contract" project which is a class library containing the .cs class generated by CrmSvcUtil and the interface that my WCF service implements, simply:

    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        Contact GetContact();
    }

Both the WCF service project and my client project reference this "service contract" project, while all three projects reference the CRM assemblies (microsoft.xrm.sdk.dll, microsoft.xrm.client.dll & microsoft.crm.sdk.proxy.dll), plus any dependencies (e.g. system.data.services & system.data.services.client).
I won't include the client code here - it really is as simple as adding a service reference to my WCF service project, instantiating the proxy and calling the GetContact() operation.
I'm really struggling to see what's wrong - looking in the class generated by CrmSvcUtil, both the Contact and the Appointment classes are decorated with the DataContract attribute so WCF should be "aware" of both? Here's a snippet of the "Contact_Appointments" property declaration within the generated Contact class:-
[Microsoft.Xrm.Sdk.RelationshipSchemaNameAttribute("Contact_Appointments")]
public System.Collections.Generic.IEnumerable<CheshireSS.MicrosoftCrm2011.Services.Appointment> Contact_Appointments
And here is a snippet of the generated Appointment class declaration:-
[System.Runtime.Serialization.DataContractAttribute()]
[Microsoft.Xrm.Sdk.Client.EntityLogicalNameAttribute("appointment")]
[System.CodeDom.Compiler.GeneratedCodeAttribute("CrmSvcUtil", "5.0.9688.1155")]
[System.Data.Services.Common.DataServiceKeyAttribute("Id")]
[System.Data.Services.IgnorePropertiesAttribute("Item", "Attributes", "EntityState", "FormattedValues", "RelatedEntities", "ExtensionData")]
[Microsoft.Xrm.Client.Metadata.EntityAttribute("AppointmentSet")]
public partial class Appointment : Microsoft.Xrm.Client.CrmEntity
We use WCF a lot here, but don't use the [DataContract] attribute (not since VS2008 SP1 when it became optional and you could just use [Serializable] objects instead). Unfortunately CrmSvcUtil doesn't decorate everything with the [Serializable] attribute, so I'm not able to force my WCF service to use the XML serializer.
Any help much appreciated
Regards
Andy

*This post is locked for comments

I have the same question (0)
  • Michael Ballhaus Profile Picture
    5 on at
    Re: Problem sending early bound entities across WCF (CRM 2011)

    Hi Andy,

    The crmutil is great but leaves a bit to be desired if you want to create a wcf to act as a proxy for Xrm. .

    There are a couple issues:

    Collections are returned as IEnumberable<> which won't get serialzed correctly, we need to return List<>
     -This is why you are seeing the problem you are.
    The entities are decorated with the datacontract attribute, which would be fine if they also marked the public members as accordingly
     -This is why your custom entity fields aren't being seen on the client

    I have successfully built a wcf that doesn't requiring the client to reference the crm sdk dll's and will bring in related entites just fine. To make it work, I created a console app that kicks off the crmsvcutil to create the proxy class, then the app reads the file and makes some updates to fix the items above.

    Here is a code sample from the latter function (I apologize for the poor formatting):

       var sb = new StringBuilder();


                    File.ReadLines(outputFile).ToList().ForEach(line =>
                    {
                        if (line.Contains("[System.Runtime.Serialization.DataContractAttribute()]"))
                        {
                            // we don't want this attribute so don't append to 'sb'
                        }
                        else if (line.Contains("System.Collections.Generic.IEnumerable"))
                        {
                            sb.AppendLine(line.Replace("System.Collections.Generic.IEnumerable", "System.Collections.Generic.List"));
                        }
                        else if (line.Contains("return System.Linq.Enumerable.Cast"))
                        {
                            var type = line.Substring((line.IndexOf('<') + 1), (line.IndexOf('>') - (line.IndexOf('<') + 1)));

                            sb.AppendLine(string.Format("\t\t\t\t\treturn new System.Collections.Generic.List<{0}>(System.Linq.Enumerable.Cast<{0}>(collection.Entities));", type));
                        }
                        else if (line.Contains("return this.GetRelatedEntities"))
                        {
                            var type = line.Substring((line.IndexOf('<') + 1), (line.IndexOf('>') - (line.IndexOf('<') + 1)));

                            sb.AppendLine(string.Format("{0} as System.Collections.Generic.List<{1}>;", line.TrimEnd(new[] { ';' }), type));
                        }
                        else
                        {
                            sb.AppendLine(line);
                        }
                    });

                    File.WriteAllText(outputFile, sb.ToString());\

     

    Hope this helps!!

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Andrés Arias – Community Spotlight

We are honored to recognize Andrés Arias as our Community Spotlight honoree for…

Leaderboard > 🔒一 Microsoft Dynamics CRM (Archived)

#1
Community Member Profile Picture

Community Member 2

#2
Christoph Pock Profile Picture

Christoph Pock 1

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans