无法为WCF Web服务序列化嵌套的nHibernate实体

时间:2012-04-27 13:23:43

标签: wcf nhibernate spring.net

我正在尝试将nHibernate,Spring和WCF结合使用。我有一个Order对象,它包含一个Customer对象。

我可以在我的服务上调用WCF方法findOrder,并且提供Order的{​​{1}}字段没有Customer注释,Web服务返回DataMember我想要。但正如预期的那样,它不包含Order详细信息。

但是,当我尝试包含Customer时,WebService失败,并查看WCF跟踪日志,我可以看到此错误:

  

System.Runtime.Serialization.SerializationException:   输入带有数据合约名称的'DecoratorAopProxy_95d4cb390f7a48b28eb6d7404306a23d'   'DecoratorAopProxy_95d4cb390f7a48b28eb6d7404306a23d:HTTP://schemas.datacontract.org/2004/07/'   不是预期的。考虑使用DataContractResolver或添加静态未知的任何类型   已知类型的列表 - 例如,通过使用KnownTypeAttribute属性或将它们添加到   传递给DataContractSerializer的已知类型列表

非常确定这是因为客户包含额外的nHibernate详细信息,但我不明白为什么WCF很乐意发送Customer,而不是Order

任何人都可以帮助我理解吗?

订单对象

Customer

客户对象

[DataContract]
[KnownType(typeof(Customer))]

public class Order
{
  // Standard properties
  [DataMember]
  public virtual int Id { get; set; }

  public virtual Enums.OrderStatus Status { get; set; }        

  [DataMember]
  [StringLength(20, ErrorMessage = "Order name must not be more than 20 characters long")]
  public virtual string Name { get; set; }

  [DataMember]
  public virtual Customer Customer { get; set; }

  [DataContract]
  ...
}

1 个答案:

答案 0 :(得分:3)

您应该使用数据传输对象(DTO)通过网络获取数据。无论如何,这是一种很好的做法,因为您不希望让您的域模型泄漏到应用程序的边界内(和之外)。

考虑一下您的域模型中的每个更改都会导致更改数据合同,从而导致新的wsdl,从而导致客户端发生更改。此外,您告诉消费者您的服务有太多关于您的应用的见解。

尽管所有这些建筑都是bla bla。 NHibernate使用代理来启用延迟加载,这些代理是序列化程序所期望的另一种类型。您可以禁用域的延迟加载以使应用程序正常工作。这是一个糟糕的主意。

<class name="Customer" table="tzCustomer" lazy="false" >