クラウドで 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()
{
}
}
}