Json.NET序列化后包含类型,保证序列化和反序列化的对象类型相同(转载)
This sample uses the TypeNameHandling setting to include type information when serializing JSON and read type information so that the create types are created when deserializing JSON.
Sample
Types
public abstract class Business { public string Name { get; set; } } public class Hotel : Business { public int Stars { get; set; } } public class Stockholder { public string FullName { get; set; } public IList<Business> Businesses { get; set; } }
Usage
Stockholder stockholder = new Stockholder { FullName = "Steve Stockholder", Businesses = new List<Business> { new Hotel { Name = "Hudson Hotel", Stars = 4 } } }; string jsonTypeNameAll = JsonConvert.SerializeObject(stockholder, Formatting.Indented, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }); Console.WriteLine(jsonTypeNameAll); // { // "$type": "Newtonsoft.Json.Samples.Stockholder, Newtonsoft.Json.Tests", // "FullName": "Steve Stockholder", // "Businesses": { // "$type": "System.Collections.Generic.List`1[[Newtonsoft.Json.Samples.Business, Newtonsoft.Json.Tests]], mscorlib", // "$values": [ // { // "$type": "Newtonsoft.Json.Samples.Hotel, Newtonsoft.Json.Tests", // "Stars": 4, // "Name": "Hudson Hotel" // } // ] // } // } string jsonTypeNameAuto = JsonConvert.SerializeObject(stockholder, Formatting.Indented, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }); Console.WriteLine(jsonTypeNameAuto); // { // "FullName": "Steve Stockholder", // "Businesses": [ // { // "$type": "Newtonsoft.Json.Samples.Hotel, Newtonsoft.Json.Tests", // "Stars": 4, // "Name": "Hudson Hotel" // } // ] // } // for security TypeNameHandling is required when deserializing Stockholder newStockholder = JsonConvert.DeserializeObject<Stockholder>(jsonTypeNameAuto, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }); Console.WriteLine(newStockholder.Businesses[0].GetType().Name); // Hotel
演示
现在我们来做个演示,新建一个.NET Core控制台项目,然后我们定义两个类Car和Person如下:
using Newtonsoft.Json; using System; namespace JsonNetTesting { public class Car { public string Name { get; set; } public string Color { get; set; } } public class Person { public string Name { get; set; } public int Age { get; set; } public Car carField; public Car CarProperty { get; set; } } class Program { static void Main(string[] args) { Person person = new Person() { Name = "Jack", Age = 35, carField = new Car() { Name = "Benz", Color = "Black" }, CarProperty = new Car() { Name = "BMW", Color = "White" } }; string json = JsonConvert.SerializeObject(person, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All, Formatting = Formatting.Indented }); Console.WriteLine(json); person = JsonConvert.DeserializeObject<Person>(json, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }); Console.WriteLine("Press key to end..."); Console.ReadKey(); } } }
可以看到当我们设置TypeNameHandling = TypeNameHandling.All后,本例中类Car和Person序列化为JSON后如下:
{ "$type": "JsonNetTesting.Person, JsonNetTesting", "carField": { "$type": "JsonNetTesting.Car, JsonNetTesting", "Name": "Benz", "Color": "Black" }, "Name": "Jack", "Age": 35, "CarProperty": { "$type": "JsonNetTesting.Car, JsonNetTesting", "Name": "BMW", "Color": "White" } }
可以看到类Car和Person被序列化为JSON后,都自动生成了一个"$type"属性,用来标识它们是从什么.NET类型序列化而来的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2016-01-19 SQL关于apply的两种形式cross apply和outer apply(转载)