我有一个与云中的 CRM 2011 通信的 WCF 服务。我使用提供的 crmsvcutil.exe 为 CRM 中的所有对象生成实体。我有一个接口(interface) IProduct
指向需要返回所有产品列表的 GetAllProducts()
。如果我在客户端(C# 控制台应用程序)时单步执行我的服务,则 Linq 查询具有预期的产品列表。但是当它试图将它返回给调用应用程序时,我得到一个错误:
InnerException 消息是“第 1 行位置 688 中的错误。元素‘http://schemas.datacontract.org/2004/07/System.Collections.Generic:value’包含来自映射到的类型的数据名称“http://schemas.microsoft.com/xrm/2011/Contracts:OptionSetValue”。反序列化器不知道映射到该名称的任何类型。考虑使用 DataContractResolver 或将与“OptionSetValue”对应的类型添加到已知类型列表中 - 例如,通过使用 KnownTypeAttribute 属性或将其添加到传递给 DataContractSerializer 的已知类型列表中。有关详细信息,请参阅 InnerException。”
。
这只发生在复杂的数据类型中。如果我返回一个简单的字符串或整数,那没有问题。作为我可以返回复杂类型的 POC,我创建了一个名为 ComplexPerson
的类和一个名为 GetPerson(int Id)
的方法来返回一个简单的对象。这很好用(因为我必须自己装饰类(class))。
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()
{
}
}
}
最佳答案
这就是我让它工作的方式。就我而言,我有三个项目:-
一个“服务契约(Contract)”类库项目,包含 CrmSvcUtil 生成的 cs 文件和我的 WCF 接口(interface)(IMyService 或其他)。该项目引用了常用的 CRM DLL(Microsoft.Xrm.Sdk、MicrosoftXrm.Client、Microsoft.Crm.Sdk.Proxy)以及它们所依赖的其他内容(例如 System.Data.Services.dll 等)。
WCF 服务项目(引用上述项目)。这里是实现上述项目中接口(interface)的.svc。该项目还引用了与上述相同的 CRM DLL。
我的客户项目。这引用了上面的服务契约(Contract)项目。它还引用了两个 CRM DLL(Microsoft.Xrm.Sdk 和 Microsoft.Xrm.Client)。您可能还需要添加一些依赖项(例如 System.Runtime.Serialization)。
现在以通常的方式添加服务引用。现在,编写您的代码以在服务代理上实例化和调用操作。假设你需要引用CRM实体类,你只需要添加一个“using xxx;” (其中 xxx 是您在 CrmSvcUtil.exe 的命令行中使用的命名空间)。
希望对你有帮助 安迪
关于WCF 反序列化 - 反序列化程序不知道映射到此名称的任何类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6101424/