3

クラウドで CRM 2011 と通信する WCF サービスがあります。提供された 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."}.

これは、複雑なデータ型でのみ発生します。単純な文字列または整数を返す場合、問題はありません。複合型を返すことができる 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()
            {

            }
        }
    }
4

1 に答える 1

2

これが私がそれを機能させる方法です。私の場合、3 つのプロジェクトがあります。

  • CrmSvcUtil によって生成された cs ファイルと、私の WCF インターフェイス (IMyService など) を含む "サービス コントラクト" クラス ライブラリ プロジェクト。このプロジェクトは、通常の CRM DLL (Microsoft.Xrm.Sdk、MicrosoftXrm.Client、Microsoft.Crm.Sdk.Proxy) と、これらが依存する他のもの (System.Data.Services.dll など) を参照します。

  • WCF サービス プロジェクト (上記のプロジェクトを参照)。上記のプロジェクトでインターフェイスを実装する .svc は次のとおりです。プロジェクトは、上記と同じ CRM DLL も参照します。

  • 私のクライアントプロジェクト。これは、上記のサービス コントラクト プロジェクトを参照します。また、2 つの CRM DLL (Microsoft.Xrm.Sdk と Microsoft.Xrm.Client) も参照しています。また、いくつかの依存関係 (System.Runtime.Serialization など) を追加する必要がある場合もあります。

次に、通常の方法でサービス参照を追加します。ここで、サービス プロキシで操作をインスタンス化して呼び出すコードを記述します。CRM エンティティ クラスを参照する必要があると仮定すると、「using xxx;」を追加するだけで済みます。(xxx は、CrmSvcUtil.exe のコマンド ラインで使用した名前空間です)。

これがアンディに役立つことを願っています

于 2011-06-30T09:19:56.983 に答える