我从WCF服务获得了以下接口:

[ServiceContract]
[ServiceKnownType("GetKnownTypes", typeof(KnownTypesProvider))]
public interface IQuerySageService
{

    [OperationContract]
    CustomerLedger GetBillingContact(string crmAccountNumber);

    [OperationContract]
    ImportCrmInvoicesResponse ImportCrmInvoices(List<New.Xrm.Entities.Invoice> invoices);


}


上面引用的方法来自此类:

internal static class KnownTypesProvider
{
    public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)
    {
        List<Type> types = new List<Type>();

        types.Add(typeof(New.Xrm.Entities.InvoiceDetail));

        return types;
    }
}


但是从客户端(CRM工作流程)调用ImportCrmInvoicesInvoice具有InvoiceDetail个子项)时,出现以下错误:


  尝试序列化参数时发生错误
  http://tempuri.org/:invoices。 InnerException消息为“类型
  带有数据合同名称的“ New.Xrm.Entities.InvoiceDetail”
  '发票明细:http://schemas.datacontract.org/2004/07/New.Xrm.Entities'
  不是预期的。考虑使用DataContractResolver或添加任何
  已知类型列表中不是静态已知的类型-例如,
  通过使用KnownTypeAttribute属性或将它们添加到
  传递给DataContractSerializer的已知类型的列表。”。请参见
  InnerException,以获取更多详细信息。”


我以为这种ServiceKnownType装饰可以达到我所读内容的目的,但显然不能。

类型(发票,发票详细信息)包含在程序集中,由客户端和服务器(名称空间New.Xrm.Entities)均引用

现在,保存这些类型的物理CS文件很大(7MB),几乎不可编辑。因此,也许我在某处缺少DataContract装饰,但是我不想在此文件中添加它。

还有其他方法可以做到这一点吗?

最佳答案

实现此目的的另一种方法是在派生子类的父DataContract类上使用KnownTypes属性。


  KnownTypeAttribute类允许您预先指定反序列化过程中应考虑的类型。


https://msdn.microsoft.com/en-us/library/ms730167(v=vs.110).aspx

KnownTypes属性可以采用类型参数,也可以在该类中提供返回有效类型数组的方法的名称。

例如:

[DataContract]
[KnownTypes(typeof(InvoiceDetail)]
public class Invoice
{
    [DataMember]
    public string SomeProperty {get; set; }
}

[DataContract]
public class InvoiceDetail : Invoice
{
}

10-07 17:22