博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Wcf序列化的循环引用问题1
阅读量:6809 次
发布时间:2019-06-26

本文共 3032 字,大约阅读时间需要 10 分钟。

1.Wcf数据契约序列化,使用的类DataContractSerializer

默认如果类不指定[DataContract],则序列化类的所有字段,并且在出现循环引用的时候回抛出异常,服务终止

msdn文档说明:

/*    * Wcf 数据契约序列化使用“DataContractSerializer”,底层是xml序列化    * 1.如果类上不指定 [DataContract],默认序列化,对象的所有属性(包括null的)    * 2.如果类上指定 [DataContract],序列化只检测 属性有 [DataMember] 的    * 3.没有显示指定忽略某字段的方式    *///创建班级Grade gradeOne = new Grade() { GradeID = 1, GradeName = "班级1" };gradeOne.Students = new List
();//添加班级下的学生Student stu = new Student();stu.ID = 1;stu.Name = "张三";//设置学生所属的班级 /* * 1.注意:如果当前子类的父类对象引用了当前父类对象抛出循环引用异常 * 解决方法1: 对于需要序列化的类显示指定契约标识 [DataContract] * 并且忽略 子类的父类对象, * 也就是 对 Grade 不指定 [DataMember] *//* * 解决方法2: * 在类的方法标记使用 [DataContract(IsReference = true)] * IsReference:如果使用标准 XML 保留对象引用数据,则为 true;否则为 false */stu.Grade = gradeOne;gradeOne.Students.Add(stu);DataContractSerializer serializer = new DataContractSerializer(gradeOne.GetType());string result = null;using (MemoryStream s = new MemoryStream()){ serializer.WriteObject(s, gradeOne); s.Seek(0, SeekOrigin.Begin); using (StreamReader r = new StreamReader(s)) { result = r.ReadToEnd(); }}Console.WriteLine(result);

默认设置(出现异常)

public class Student{    public int ID { get; set; }    public string Name { get; set; }    public Grade Grade { get; set; }}public class Grade{    public int GradeID { get; set; }    public string GradeName { get; set; }    public List
Students { get; set; }}

解决方法1,忽略导致循环引用的属性:

这样的缺点:就是在客户端获取到学生对象,不能直接也得到学生所属的班级对象

[DataContract]public class Student{    [DataMember]    public int ID { get; set; }    [DataMember]    public string Name { get; set; }    [DataMember]    public Grade Grade { get; set; }}[DataContract]public class Grade{    [DataMember]    public int GradeID { get; set; }    [DataMember]    public string GradeName { get; set; }    [DataMember]    public List
Students { get; set; }}

序列化结果:

1
班级1
1
张三

解决方法2(推荐),在DataContract上使用IsReference参数,并且设置为true,

互操作引用说明:

IsReferences:如果使用标准 XML 保留对象引用数据,则为 true;否则为 false。

[DataContract(IsReference = true)]public class Student{    [DataMember]    public int ID { get; set; }    [DataMember]    public string Name { get; set; }    [DataMember]    public Grade Grade { get; set; }}[DataContract(IsReference = true)]public class Grade{    [DataMember]    public int GradeID { get; set; }    [DataMember]    public string GradeName { get; set; }    [DataMember]    public List
Students { get; set; }}

或者在初始化对象的时候指定

DataContractSerializer serializer = new DataContractSerializer(typeof(Parent),          "Parent",          string.Empty,          null,          int.MaxValue,          false,          true,          null,          null);

序列化结果:

1
班级1
1
张三

转载地址:http://dptwl.baihongyu.com/

你可能感兴趣的文章
Android CircleMenu:旋转转盘选择Menu
查看>>
XML实体注入漏洞
查看>>
【Java小工匠聊密码学】--对称加密--DES
查看>>
调用Thread类的方法:public final String getName() 为什么得到的线程对象的名称默认是:Thread-0、Thread-1、Thread-2、...呢?...
查看>>
Shell脚本里的双冒号是什么意思
查看>>
java基础学习_GUI_如何让Netbeans的东西Eclipse能访问、GUI(图形用户接口)_day25总结...
查看>>
从零开始学 Web 之 CSS(三)链接伪类、背景、行高、盒子模型、浮动
查看>>
java多线程--信号量Semaphore的使用
查看>>
中国存储芯片进入战略关键期
查看>>
市场上的视觉图像采集卡软硬功能对比
查看>>
阿里专家与你分享:你必须了解的Java多线程技术
查看>>
张高兴的 Windows 10 IoT 开发笔记:三轴数字罗盘 HMC5883L
查看>>
rocketmq 同步双写
查看>>
细数国内无人机的江湖门派
查看>>
张高兴的 Windows 10 IoT 开发笔记:部署 ASP.NET Core 2 应用
查看>>
Waymo已经开始绘制亚特兰大地图数据,自动驾驶汽车路测地点又添新城
查看>>
ARM 和 RISC-V 公然开撕,GNOME 之父指责 ARM
查看>>
日本将推出“隐形列车”,你要去体验一番吗?
查看>>
15 篇最新 AI 论文来袭!NLP、CV...人人有份 | 本周值得读
查看>>
Maven查看依赖树
查看>>