我正在实现一个示例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
的数量为 Process
而且每个 Process
都有 User
与之关联 .
[OperationContract]
User GetUser();
当我从WCFTestClient运行此方法时,我得到一个异常,这是可以理解的,因为每当我们在用户中序列化ProcessOfUser时,它在trun中将再次序列化User .
为避免这种情况,请在Process [DataContract]中使用 I remove the DataMember attribute from UserOfProcess . 它工作正常 .
My question is ,
1.这是解决这个问题的正确方法,还是 Is there some other way to this
?我还发现 [IgnoreDataMember]
属性以避免其序列化 .
2.我可以通过编程方式添加或删除 [DataMember]
属性吗?
1 回答
您可以使用[IsReference]属性告诉WCF解决循环依赖关系 .
但是,在将自己用于业务对象之后,我遇到了太多的复杂问题,最后使用了显式的DTO,并且有效地完成了你所做的事情并省略了循环引用 . 当DTO转换回业务对象时,我在客户端再次连接引用 .
但是对于简单的对象图,IsReference应该没问题 .
EDIT :关于DTO
正如我所说的那样,我最初通过网络对域对象进行了序列化,但最终它变得太乱了 .
首先是因为我还将这些相同的对象序列化为持久性,所以我最终遇到了冲突的序列化需求,但主要是因为DataContractSerializer不调用构造函数,所以你不能保证你的对象是有效的 . 我最终有了大的
[OnDeserialized]
方法来确保成员不是null等 . 由于WCF序列化对象图的方式,在集合成员上执行此操作会导致严重的麻烦 .使用DTO使它全部消失并暴露出一个非常干净的对象,显示出服务的确切内容 . 你得到一个DTO然后可以做你的映射知道一切都到位而不是一些奇怪的半序列化状态 . 如果你的域名对象非常简单,你可能会侥幸逃脱,但我个人不会在痛苦引起我之后推荐它 .
DTO非常简单:
现在我的所有收藏品都是简单的数组 . 业务对象中的字典等在客户端完全构建,而不是尝试序列化它们 .