3

我正在实现一个示例 WCF 服务以了解如何DataContractSerializer序列化双向实体。我有以下数据合同。

[DataContract]
public class Process
{
    [DataMember]
    public string ProcessName { get; set; }
    [DataMember]
    public string Memory { get; set; }
    [DataMember]
    public User UserOfProcess { get; set; }
}

[DataContract]
public class User
{
    [DataMember]
    public string UserID { get; set; }
    [DataMember]
    public string UserName { get; set; }
    [DataMember]
    public List<Process> ProcessesOfUser { get; set; }
}

正如您可能注意到的那样,User有 number ofProcess并且 eachProcessUser与它相关联。

  [OperationContract]
  User GetUser();

当我从 WCFTestClient 运行此方法时,我得到一个异常,这是可以理解的,因为每当我们在 User 中序列化 ProcessOfUser 时,它都会再次序列化 User。

为了避免这种情况,我从Process[DataContract] 中的 UserOfProcess 中删除了 DataMember 属性。它工作正常。

我的问题是
1.这是解决这个问题的正确方法,还是Is there some other way to this?我还找到了[IgnoreDataMember]避免其序列化的属性。
2. 我可以通过[DataMember]编程方式添加或删除属性吗?

4

1 回答 1

3

您可以使用[IsReference]属性告诉 WCF 解决循环依赖关系。

但是,在我自己在业务对象上使用它之后,我遇到了太多复杂情况,最终改用显式 DTO,并有效地完成了你所做的事情并省略了循环引用。当 DTO 转换回业务对象时,我在客户端再次连接引用。

IsReference 对于简单的对象图应该没问题。

编辑:关于 D​​TO

正如我所说,我最初通过网络对域对象进行了序列化,但最终变得过于混乱。

首先,因为我还序列化了那些相同的对象以实现持久性,所以我最终遇到了冲突的序列化需求,但主要是因为 DataContractSerializer 不调用构造函数,所以你不能保证你的对象是有效的。我最终拥有了[OnDeserialized]确保成员不为空等的大型方法。由于 WCF 序列化对象图的方式,对集合成员执行此操作引起了巨大的头痛。

使用 DTO 可以让这一切都消失,并公开一个非常干净的对象,准确地显示服务中发生了什么。你得到一个 DTO,然后可以在知道一切就绪而不是处于某种奇怪的半序列化状态的情况下进行映射。如果您的域对象真的很简单,您可能会侥幸成功,但在给我带来痛苦之后,我个人不会推荐它。

DTO 非常简单:

[DataContract]
public class UserProcessesDTO
{
    [DataMember] public string       UserID          { get; set; }
    [DataMember] public string       UserName        { get; set; }
    [DataMember] public ProcessDTO[] Processes       { get; set; }
}

[DataContract]
public class ProcessDTO
{
    [DataMember] public string       ProcessName     { get; set; }
    [DataMember] public string       Memory          { get; set; }
}

我所有的收藏现在都像简单的数组一样通过网络传输。业务对象中的字典等在客户端被干净地构建,而不是试图序列化它们。

于 2012-06-11T10:35:17.830 回答