加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

json.Net学习笔记(十) 保持对象引用

发布时间:2020-12-16 19:22:16 所属栏目:百科 来源:网络整理
导读:json.Net学习笔记(十) 保持对象引用 2011年6月11日 联系商易上海电子商务网站建设,了解更多 默认情况下,Json.Net将通过对象的值来序列化它遇到的所有对象。如果工个list包含两个Person引用,这两个引用都指向同一个对象,Json序列化器将输出每一个引用的所

默认情况下,Json.Net将通过对象的值来序列化它遇到的所有对象。如果工个list包含两个Person引用,这两个引用都指向同一个对象,Json序列化器将输出每一个引用的所有名称和值。


定义类:


public class Person
{
public DateTime BirthDate { get; set; }
public DateTime LastModified { get; set; }
public string Name { get; set; }
}


测试:


Person p = new Person()
{
BirthDate = new DateTime(1985,11,27,DateTimeKind.Utc),
LastModified = new DateTime(2010,12,20,
Name = "James"
};
List<Person> people = new List<Person>();
people.Add(p);
people.Add(p);
string json = JsonConvert.SerializeObject(people,Formatting.Indented);
Console.WriteLine(json);


输出结果:


[
{
"BirthDate": "/Date(501897600000)/",
"LastModified": "/Date(1292803200000)/",
"Name": "James"
},
{
"BirthDate": "/Date(501897600000)/",
"Name": "James"
}
]


在大多数情况下这是期望的结果,但是在某些场景下,将list中的第二项作为第一项的一个引用来输出会是一个更好的解决方案。如果上面的Json现在被反序列化,返回的list会包含两个完全分离的对象,它们具有相同的值。通过值来输出引用也会在对象上导致循环引用的发生。


>PreserveReferencesHandling


string json2 = JsonConvert.SerializeObject(people,Formatting.Indented,
new JsonSerializerSettings() { PreserveReferencesHandling = PreserveReferencesHandling.Objects });
Console.WriteLine(json2);


输出结果:


[
{
"$id": "1",
"BirthDate": "/Date(501897600000)/",
{
"$ref": "1"
}
]


List<Person> deserializedPeople = JsonConvert.DeserializeObject<List<Person>>(json2,
new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects });


Console.WriteLine(deserializedPeople.Count);// 2


Person p1 = deserializedPeople[0];
Person p2 = deserializedPeople[1];
Console.WriteLine(p1.Name);// James
Console.WriteLine(p2.Name);// James
bool equal = Object.ReferenceEquals(p1,p2);// true


在list中的第一个Person被序列化时增加了一个额外的对象Id,现在第二个Person对象仅仅是第一个的引用。


现在使用PreserveReferencesHandling后,在序列化时只创建了一个Person对象,list中包含它的两个引用,原来我们叫作反射(mirroring) 。


>IsReference on JsonObjectAttribute,JsonArrayAttribute and JsonPropertyAttribute


在对象序列化器上设置PreserveReferencesHandling,将会改变所有对象被序列化和反序列化的方式。为了更加细致地控制对象和成员被序列化为一个引用,可以在JsonObjectAttribute,JsonArrayAttribute 和 JsonPropertyAttribute上使用IsReference 属性.


在JsonObjectAttribute,JsonArrayAttribute 上设置IsReference 为true,意味着Json序列化器总是会序列这个类型为一个引用。在JsonPropertyAttribute上设置IsReference为true将只序列化这个属性为一个引用。


[JsonObject(IsReference = true)]
public class EmployeeReference
{
public string Name { get; set; }
public EmployeeReference Manager { get; set; }
}


测试:


List<EmployeeReference> empList = new List<EmployeeReference>();
empList.Add(empRef);
empList.Add(empRef);
string empRefJson = JsonConvert.SerializeObject(empList,Formatting.Indented);
Console.WriteLine(empRefJson);


输出结果:


[
{
"$id": "1",
"Name": "IsReference",
"Manager": null
},
{
"$ref": "1"
}
]


>IReferenceResolver


要想定制引用的生成方式,可以继承自IReferenceResolver接口来使用Json序列化器。

json.Net学习笔记(十) 保持对象引用
2011年6月11日联系商易上海电子商务网站建设,了解更多

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读