2011-05-23 75 views
2

我有一個與雲中的CRM 2011進行通信的WCF服務。我使用提供的crmsvcutil.exe爲CRM中的所有對象生成實體。我有一個接口IProduct,指向GetAllProducts(),需要返回所有產品的列表。如果我在客戶端(C#控制檯應用程序)時通過我的服務,Linq查詢具有預期的產品列表。但是當它試圖將其返回給調用應用程序時,出現錯誤:WCF反序列化 - 反序列化器不知道映射到該名稱的任何類型

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

這就是我如何得到它的工作。在我來說,我有三個項目: -

  • 一種包含由CrmSvcUtil產生的CS文件「服務合同」類庫項目,和我的WCF接口(IMyService或其他)。此項目引用通常的CRM DLL(Microsoft.Xrm.Sdk,MicrosoftXrm.Client,Microsoft.Crm.Sdk.Proxy)以及這些依賴的其他(如System.Data.Services.dll等)。

  • WCF服務項目(引用上述項目)。在這裏是在上面的項目中實現接口的.svc。該項目還引用了與上述相同的CRM DLL。

  • 我的客戶項目。這引用了上述服務合同項目。它還引用了兩個CRM DLL(Microsoft.Xrm.Sdk & Microsoft.Xrm.Client)。您可能還需要添加一些依賴項(例如System.Runtime.Serialization)。

現在以通常的方式添加服務引用。現在,編寫代碼來實例化並調用服務代理上的操作。假設你需要引用CRM實體類,你只需要添加一個「使用xxx;」 (其中xxx是您在CrmSvcUtil.exe命令行中使用的命名空間)。

希望這會有幫助 Andy