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 ListStudents { 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 ListStudents { 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 ListStudents { get; set; }}
或者在初始化对象的时候指定
DataContractSerializer serializer = new DataContractSerializer(typeof(Parent), "Parent", string.Empty, null, int.MaxValue, false, true, null, null);
序列化结果:
1 班级1 1 张三