WCF DataContract双向实体或循环依赖的序列化

时间:2012-06-11 10:30:32

标签: .net wcf datacontractserializer

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

[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的{​​{1}}数量已经Process,而Process每个User都与 [OperationContract] User GetUser(); 相关联。

Is there some other way to this

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

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

我的问题是
1.这是解决此问题的正确方法,还是[IgnoreDataMember]?    我还找到[DataMember]属性以避免其序列化 2.我可以通过编程方式添加或删除{{1}}属性吗?

1 个答案:

答案 0 :(得分:3)

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

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

IsReference应该适用于简单的对象图。

编辑:关于DTO的

正如我所说的那样,我最初通过网络对域对象进行了序列化,但最终它变得太乱了。

首先,因为我还将这些相同的对象序列化为持久性,所以我最终遇到了冲突的序列化需求,但主要是因为DataContractSerializer不调用构造函数,所以你不能保证你的对象是有效的。我最终有了大[OnDeserialized]个方法来确保成员不是null等。由于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; }
}

现在我的所有收藏品都是简单的数组。业务对象中的字典等在客户端完全构建,而不是尝试序列化它们。