1

我正在尝试一起使用 nHibernate、Spring 和 WCF。我有一个Order对象,其中包含一个Customer对象。

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

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

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

Order很确定这是因为客户包含额外的 nHibernate 详细信息,但我不明白为什么 WCF 很乐意发送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 = "";
    ...
}
4

1 回答 1

3

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

想想像你的领域模型的每一次变化都会导致你的数据契约发生变化,从而产生一个新的wsdl,从而导致客户端发生变化。此外,您告诉服务的消费者对您的应用程序的太多见解。

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

<class name="Customer" table="tzCustomer" lazy="false" >
于 2012-04-27T13:35:46.367 回答