WCF反序列化 - 反序列化器不知道映射到此名称的任何类型

时间:2011-05-23 18:40:33

标签: wcf datacontract deserialization dynamics-crm-2011

我有一个WCF服务,可以在云端与CRM 2011进行通信。我使用提供的crmsvcutil.exe为CRM中的所有对象生成实体。我有一个指向IProduct的接口GetAllProducts(),需要返回所有产品的列表。如果我在客户端(C#控制台应用程序)中通过我的服务,Linq查询具有预期的产品列表。但是当它试图将它返回给调用应用程序时,我收到一个错误:

The InnerException message was 'Error in line 1 position 688. Element 'http://schemas.datacontract.org/2004/07/System.Collections.Generic:value' contains data from a type that maps to the name 'http://schemas.microsoft.com/xrm/2011/Contracts:OptionSetValue'. The deserializer has no knowledge of any type that maps to this name. Consider using a DataContractResolver or add the type corresponding to 'OptionSetValue' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details."}

这仅适用于复杂数据类型。如果我返回一个简单的字符串或int,那里没有问题。作为我可以返回复杂类型的POC,我创建了一个名为ComplexPerson的类,以及一个名为GetPerson(int Id)的方法来返回一个简单的对象。这很好(因为我必须自己装饰课程)。

    namespace Microsoft.ServiceModel.Samples
    {
        [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
        public interface IProduct
        {
            [OperationContract]
            [ServiceKnownType(typeof(Product))]
            List<Product> GetAllProducts();

            [OperationContract]
            ComplexPerson GetPerson(int Id);
        }

        public class ProductService : IProduct
        {
            private List<Product> _products;
            private OrganizationServiceProxy _serviceProxy;
            private IOrganizationService _service;

            public List<Product> GetAllProducts()
            {
                _products = new List<Product>();
                try
                {
                    //connect to crm
                        var query = orgContext.CreateQuery<Product>();

                        foreach (var p in query)
                        {
                            if (p is Product)
                                _products.Add(p as Product);
                        }

                        return _products;
                }

                // Catch any service fault exceptions that Microsoft Dynamics CRM throws.
                catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex)
                {
                    // You can handle an exception here or pass it back to the calling method.
                    return null;
                }
            }

            public ComplexPerson GetPerson(int Id)
            {
                ComplexPerson person = new ComplexPerson();

                switch (Id)
                {
                    case 2:
                        person.FirstName = "Tim";
                        person.LastName = "Gabrhel";
                        person.BirthDate = new DateTime(1987, 02, 13, 0, 0, 0);
                        break;
                    default:
                        break;
                }

                return person;
            }

        }

        [DataContract]
        public class ComplexPerson
        {
            [DataMember]
            public string FirstName;
            [DataMember]
            public string LastName;
            [DataMember]
            public DateTime BirthDate;

            public ComplexPerson()
            {

            }
        }
    }

1 个答案:

答案 0 :(得分:1)

这就是我开始工作的方式。就我而言,我有三个项目: -

  • “服务合同”类库项目,包含由CrmSvcUtil和我的WCF接口(IMyService或其他)生成的cs文件。此项目引用了常用的CRM DLL(Microsoft.Xrm.Sdk,MicrosoftXrm.Client,Microsoft.Crm.Sdk.Proxy)以及其他依赖的(例如System.Data.Services.dll等)。

  • WCF服务项目(引用上述项目)。这里是在上面的项目中实现接口的.svc。该项目还引用了与上述相同的CRM DLL。

  • 我的客户项目。这引用了上述服务合同项目。它还引用了两个CRM DLL(Microsoft.Xrm.Sdk&amp; Microsoft.Xrm.Client)。您可能还需要添加一些依赖项(例如System.Runtime.Serialization)。

现在以通常的方式添加服务引用。现在,编写代码以实例化并调用服务代理上的操作。假设您需要引用CRM实体类,您只需要添加“使用xxx;” (其中xxx是您在CrmSvcUtil.exe命令行中使用的命名空间)。

希望这会有所帮助 安迪