Wcf序列化的循环引用问题1

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

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

msdn文档说明:https://msdn.microsoft.com/library/system.runtime.serialization.datacontractserializer.aspx

/*
    * Wcf 数据契约序列化使用“DataContractSerializer”,底层是xml序列化
    * 1.如果类上不指定 [DataContract],默认序列化,对象的所有属性(包括null的)
    * 2.如果类上指定 [DataContract],序列化只检测 属性有 [DataMember] 的
    * 3.没有显示指定忽略某字段的方式
    */
//创建班级
Grade gradeOne = new Grade() { GradeID = 1, GradeName = "班级1" };
gradeOne.Students = new List<Student>();
//添加班级下的学生
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<Student> 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<Student> Students { get; set; }
}

序列化结果:

<?xml version="1.0" encoding="utf-8"?>
<Grade xmlns="http://schemas.datacontract.org/2004/07/Test" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <GradeID>1</GradeID>
  <GradeName>班级1</GradeName>
  <Students>
    <Student>
      <Grade i:nil="true"/>
      <ID>1</ID>
      <Name>张三</Name>
    </Student>
  </Students>
</Grade>

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

互操作引用说明:https://msdn.microsoft.com/zh-cn/library/cc656708(v=vs.110).aspx

[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<Student> Students { get; set; }
}

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

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

序列化结果:

<?xml version="1.0" encoding="utf-8"?>
<Grade xmlns="http://schemas.datacontract.org/2004/07/Test" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" z:Id="i1">
  <GradeID>1</GradeID>
  <GradeName>班级1</GradeName>
  <Students>
    <Student z:Id="i2">
      <Grade z:Ref="i1"/>
      <ID>1</ID>
      <Name>张三</Name>
    </Student>
  </Students>
</Grade>
时间: 2024-10-07 23:56:45

Wcf序列化的循环引用问题1的相关文章

解决MVC Json序列化的循环引用问题/EF Json序列化循引用问题---Newtonsoft.Json

1..Net开源Json序列化工具Newtonsoft.Json中提供了解决序列化的循环引用问题: 方式1:指定Json序列化配置为 ReferenceLoopHandling.Ignore 方式2:指定 JsonIgnore忽略 引用对象 实例1,解决MVC的Json序列化引用方法: step1:在项目上添加引用 Newtonsoft.Json程序包,命令:Insert-Package Newtonsoft.Json step2:在项目中添加一个类,继承JsonResult,代码如下: ///

EntityFramework中Json序列化的循环引用问题解决--Newtonsoft.Json

1.在使用EF时,由于数据库主外键关联,将对象进行Json序列化时会遇到循环引用的问题 //EF 中由于数据库主外键关联,对象的序列化经常出现循环引用问题 //使用.Net 自带的序列化工具,序列化出现循环引用问题 List<student> list = _Context.students.ToList(); JavaScriptSerializer ser = new JavaScriptSerializer(); string str = ser.Serialize(list); Con

一个C#序列化时循环引用的问题

以前一直没搞懂为什么C#在做对象序列化时(Json序列化,XML序列化等)有时候会出现循环引用的问题,下面写了个例子,类People有一个属性引用了类Child,而类Child也有一个属性引用了类People,并且两个属性的get访问器中都会new一个彼此类型的对象,这样在访问People类的Child属性的时候就会new一个Child对象,在访问Child类的People属性的时候又会new一个People对象.所以C#序列化方法在序列化People类的Child属性时又会去序列化Child属

lua序列化(支持循环引用)

lua序列化 支持key类型为string, number 支持value类型为string, number, table 支持循环引用 支持加密序列化 支持loadstring反序列化 使用示例 local t = { a = 1, b = 2} local g = { c = 3, d = 4, t} t.rt = g local ser_str = ser(g) local unser_table = loadstring(sered)() 原理详解 采用递归序列化表的方式实现,并且支持循

Xml序列化自引用/循环引用问题2

1.类定义: public class Student { public int ID { get; set; } public string Name { get; set; } //[XmlIgnore] public Grade Grade { get; set; } } public class Grade { public int GradeID { get; set; } public string GradeName { get; set; } public List<Studen

Xml序列化自引用/循环引用问题1

1.定义类 public class Student { public int ID { get; set; } public string Name { get; set; } //[XmlIgnore] public Student StudentInfo { get; set; } } 2.执行序列化操作,如果内部对象引用自己,xml序列化抛出异常“检测到循环引用” Student stu = new Student(); stu.ID = 1; stu.Name = "张三";

解决.Net MVC EntityFramework Json 序列化循环引用问题.

以前都是到处看博客,今天小菜也做点贡献,希望能帮到大家. 废话不多说,直接进入正题. 用过.net MVC的同学应该都被json序列化报循环引用错误这个问题骚扰过.网上有一些解决办法,但是都治标不治本.如在引发异常的属性上加上[ScriptIgnore]或者[JsonIgnore],又或者用db.Configuration.ProxyCreationEnabled = false;这些解决办法都存在问题且需要多处修改并且测试.本小菜之前一直被其骚扰,就在前两天我决定一定要找到比较优的解决办法,g

WCF+Nhibernate循环引用导致序列化的问题

WCF+Nhibernate 在查询中只要涉及到表关联,都会存在一个循环引用而导致客户端不能反序列化的问题. 解决的办法: 1.多对一关联中,设置lazy="false". 2.一对多关联中,配置文件的属性使用bag类型,实体类中对应的属性为强类型的集合IList<类型>,而不能为弱类型IList,否则客户端反序列化生成的代码里面对应的属性为IList<Object>,造成客户端无法反序列化到对应的类型. 3.实体类的数据契约配置加上IsReference=tr

在使用Linq to SQL并序列化一个数据对象的时候报System.InvalidOperationException异常,序列化类型XXX的对象时检测到循环引用。

在使用Linq to SQL并序列化一个数据对象的时候报System.InvalidOperationException异常,序列化类型 的对象时检测到循环引用. 异常信息(部分): System.Web.Services.Protocols.SoapException: 服务器无法处理请求. ---> System.InvalidOperationException: 生成 XML 文档时出错. ---> System.InvalidOperationException: 序列化类型 Web