无法为 WCF Web 服务序列化嵌套的 nHibernate 实体 [英] Can't serialize nested nHibernate entity for WCF web service

查看:29
本文介绍了无法为 WCF Web 服务序列化嵌套的 nHibernate 实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to use nHibernate, Spring and WCF together. I've got an Order object, and that contains a Customer object.

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

I can call a WCF method findOrder on my service, and providing the Order's Customer field does not have a DataMember annotation, the Web Service returns the Order I wanted. It does not contain the Customer details though, as expected.

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

But when I try to include the Customer as well, the WebService fails, and looking in the WCF trace logs, I can see this error:

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

System.Runtime.Serialization.SerializationException: Type 'DecoratorAopProxy_95d4cb390f7a48b28eb6d7404306a23d' with data contract name 'DecoratorAopProxy_95d4cb390f7a48b28eb6d7404306a23d:http://schemas.datacontract.org/2004/07/' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer

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

Pretty sure this is because the Customer contains extra nHibernate details, but I don't understand why WCF would be happy to send the Order, but not the 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]
  ...
}

客户对象

public class Customer
{
    public virtual int CustomerId { get; set; }

    [DataMember]
    private string name = "";
    ...
}

推荐答案

您应该使用数据传输对象 (DTO) 通过网络获取数据.无论如何,这是一个很好的做法,因为您不想让域模型泄漏到(或流出)应用程序的边界.

You should use a data transfer objects (DTO) to get your data over the wire. This is good practice anyway as you do not want to let your domain model leak into (and out of) the boundaries of your application.

考虑诸如域模型中的每一次更改都会导致数据契约的更改,从而产生新的 wsdl,从而导致客户端发生更改之类的事情.此外,您向服务的消费者提供了太多有关您的应用程序的见解.

Think about things like every change in your domain model results in a change of your data contract, resulting in a new wsdl, resulting in a change on the client. In addition you are telling the consumer of your service too many insights of your aplication.

尽管有这些建筑bla bla.NHibernate 使用代理来启用延迟加载,这些代理的类型不同于序列化程序所期望的类型.您可以为您的域禁用延迟加载以使应用程序正常工作.恕我直言,这是个坏主意.

Despite all this architectural bla bla. NHibernate uses proxies to enable lazy loading, those proxies are of another type than you serializer expects. You can disable lazy loading for your domain to get the application working. This is imho a bad idea.

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

这篇关于无法为 WCF Web 服务序列化嵌套的 nHibernate 实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆