我正在尝试将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]
...
}
答案 0 :(得分:3)
您应该使用数据传输对象(DTO)通过网络获取数据。无论如何,这是一种很好的做法,因为您不希望让您的域模型泄漏到应用程序的边界内(和之外)。
考虑一下您的域模型中的每个更改都会导致更改数据合同,从而导致新的wsdl
,从而导致客户端发生更改。此外,您告诉消费者您的服务有太多关于您的应用的见解。
尽管所有这些建筑都是bla bla。 NHibernate使用代理来启用延迟加载,这些代理是序列化程序所期望的另一种类型。您可以禁用域的延迟加载以使应用程序正常工作。这是一个糟糕的主意。
<class name="Customer" table="tzCustomer" lazy="false" >