当前位置: 首页 > news >正文

序列化详解

文章目录

序列化详解

1、序列化概念

(1)核心作用
  • 序列化:将对象转换为可存储/传输的格式(如二进制、JSON、XML),用于数据持久化(保存到文件/数据库)、网络传输(Socket通信)等场景。
  • 反序列化:将序列化数据还原为对象实例。
(2)必需标记
  • 类需添加 [Serializable] 特性,否则抛出 SerializationException
[Serializable]
public class Person {public string Name { get; set; }public int Age { get; set; }
}
  • 排除字段:用 [NonSerialized] 标记不序列化的字段。

️ 2、序列化常用方式

(1)二进制序列化(高效紧凑)
  • 优点:速度快,数据体积小。
  • 缺点:仅限 .NET 平台,安全性较低(易受恶意数据攻击)。
using System.Runtime.Serialization.Formatters.Binary;
// 序列化 
BinaryFormatter formatter = new BinaryFormatter();
using (FileStream stream = new FileStream("data.dat", FileMode.Create)) {formatter.Serialize(stream, person); // person 为 Person 对象
}
// 反序列化 
using (FileStream stream = new FileStream("data.dat", FileMode.Open)) {Person restored = (Person)formatter.Deserialize(stream);
}
(2)XML 序列化(跨平台可读)
  • 优点:跨平台兼容,人类可读。
  • 缺点:不支持私有字段,数据体积较大。
using System.Xml.Serialization;
// 序列化
XmlSerializer serializer = new XmlSerializer(typeof(Person));
using (TextWriter writer = new StreamWriter("data.xml")) {serializer.Serialize(writer, person);
}
// 反序列化 
using (TextReader reader = new StreamReader("data.xml")) {Person restored = (Person)serializer.Deserialize(reader);
}
(3)JSON 序列化(轻量通用)
  • 优点:轻量级,广泛用于 Web API。
  • 缺点:需第三方库(如 Newtonsoft.Json)。
using Newtonsoft.Json; // 需安装 NuGet 包 Newtonsoft.Json 
// 序列化 
string json = JsonConvert.SerializeObject(person);
File.WriteAllText("data.json", json);
// 反序列化
Person restored = JsonConvert.DeserializeObject<Person>(json);
(4)选型建议
场景推荐方式工具类/库
高性能 .NET 通信二进制序列化BinaryFormatter
跨平台/Web APIJSON 序列化Newtonsoft.JsonSystem.Text.Json
配置文件/可读性需求XML 序列化XmlSerializer
安全敏感场景JSON + 加密验证System.Text.Json + JWT
(5)安全风险
  • BinaryFormatter 易受反序列化攻击(如注入恶意代码),.NET 5+ 已标记为过时。
  • 替代方案:优先使用 JsonSerializer(System.Text.Json)或 XmlSerializer

3、Newtonsoft.Json

(1)安装依赖包
Install-Package Newtonsoft.Json
(2)基础操作
  • 字符串
// 序列化对象 → JSON 字符串
string json = JsonConvert.SerializeObject(obj, Formatting.Indented); // 缩进美化 // 反序列化 JSON → 对象 
var obj = JsonConvert.DeserializeObject<T>(json);
  • JSON文件读写
// 写入 JSON 文件 
File.WriteAllText("data.json", JsonConvert.SerializeObject(data, Formatting.Indented));// 读取并解析 JSON 文件 
string json = File.ReadAllText("data.json");
var data = JsonConvert.DeserializeObject<Model>(json);
(3)空值忽略处理
  • 场景:API响应中忽略空值和特定字段
public class User 
{[JsonProperty("id")] // 自定义序列化名称 public int UserId { get; set; }public string Name { get; set; }[JsonIgnore] // 完全忽略此字段public string Password { get; set; }[JsonProperty(NullValueHandling = NullValueHandling.Ignore)] // 仅忽略空值public string Email { get; set; }
}// 动态移除字段 + 全局配置
var user = new User { UserId = 1, Name = "Alice", Email = null };
var settings = new JsonSerializerSettings 
{NullValueHandling = NullValueHandling.Ignore, // 全局忽略空值 Formatting = Formatting.Indented 
};// 动态操作JSON节点 
JObject jo = JObject.FromObject(user, JsonSerializer.Create(settings));
jo.Remove("Password"); // 动态移除字段(即使未标记JsonIgnore)
string json = jo.ToString();// 输出结果:仅包含非空字段 
/* {"id": 1,"Name": "Alice"
} */
(4)处理循环引用
public class Department 
{public string Name { get; set; }public List<Employee> Employees { get; set; } // 双向引用 
}public class Employee
{public string Name { get; set; }public Department Department { get; set; } // 引用上级
}// 配置循环引用处理
var settings = new JsonSerializerSettings 
{PreserveReferencesHandling = PreserveReferencesHandling.Objects, // 解决循环引用ReferenceLoopHandling = ReferenceLoopHandling.Serialize 
};var dept = new Department { Name = "HR" };
var emp = new Employee { Name = "Bob", Department = dept };
dept.Employees = new List<Employee> { emp };string json = JsonConvert.SerializeObject(dept, settings);
// 输出包含 $id 和 $ref 标识符,避免堆栈溢出 
(5)自定义转换器
// 自定义转换器
public class UnixDateTimeConverter : JsonConverter
{public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer){var date = (DateTime)value;writer.WriteValue((date.ToUniversalTime() - new DateTime(1970, 1, 1)).TotalSeconds);}public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer){return DateTime.UnixEpoch.AddSeconds((long)reader.Value);}public override bool CanConvert(Type objectType) => objectType == typeof(DateTime);
}// 使用自定义转换器 
public class Event 
{[JsonConverter(typeof(UnixDateTimeConverter))]public DateTime EventTime { get; set; }
}// 序列化
var eventObj = new Event { EventTime = DateTime.Now };
string json = JsonConvert.SerializeObject(eventObj);
// 输出:{"EventTime":1678901234}
(6)日期格式与枚举处理
var settings = new JsonSerializerSettings
{DateFormatString = "yyyy-MM-ddTHH:mm:ssZ", // ISO8601格式 Converters = { new StringEnumConverter() } // 枚举转字符串
};public class Order 
{public DateTime CreateTime { get; set; }public OrderStatus Status { get; set; }
}public enum OrderStatus { Pending, Shipped }var order = new Order { CreateTime = DateTime.Now, Status = OrderStatus.Pending };
string json = JsonConvert.SerializeObject(order, settings);
// 输出:{"CreateTime":"2023-10-11T13:45:00Z","Status":"Pending"}
(7)流式处理超大JSON
using (var streamReader = new StreamReader("large-file.json"))
using (var jsonReader = new JsonTextReader(streamReader))
{while (jsonReader.Read()){if (jsonReader.TokenType == JsonToken.StartObject){var obj = JObject.Load(jsonReader);Console.WriteLine(obj["id"]); // 逐对象处理}}
}
(8)最佳实践
  • 复用JsonSerializerSettings实例
  • 敏感字段用[JsonIgnore]代替手动移除
  • 优先用 JsonConvert 静态方法简化调用
  • 完整配置模板
var settings = new JsonSerializerSettings
{// 基础配置Formatting = Formatting.Indented,ContractResolver = new CamelCasePropertyNamesContractResolver(), // 驼峰命名// 空值处理 NullValueHandling = NullValueHandling.Ignore,DefaultValueHandling = DefaultValueHandling.Ignore,// 高级特性DateParseHandling = DateParseHandling.DateTimeOffset,Converters = { new StringEnumConverter(),new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AdjustToUniversal }},// 循环引用 ReferenceLoopHandling = ReferenceLoopHandling.Ignore,PreserveReferencesHandling = PreserveReferencesHandling.None 
};

4、Newtonsoft集成到ASP.NETCore

(1)安装依赖包
Install-Package Newtonsoft.Json 
Install-Package Microsoft.AspNetCore.Mvc.NewtonsoftJson 
(2)全局配置复用
  • Startup.ConfigureServices 全局配置 JsonSerializerSettings
    • 所有控制器自动复用同一配置,避免重复创建开销
    • 统一处理日期、空值、枚举等规则
public void ConfigureServices(IServiceCollection services)
{// 创建全局唯一的 JsonSerializerSettings 实例 var jsonSettings = new JsonSerializerSettings {Formatting = Formatting.Indented,NullValueHandling = NullValueHandling.Ignore,ContractResolver = new CamelCasePropertyNamesContractResolver(),DateFormatString = "yyyy-MM-ddTHH:mm:ssZ",Converters = { new StringEnumConverter() }};services.AddControllers().AddNewtonsoftJson(options => {options.SerializerSettings = jsonSettings; // 复用实例 });
}
(3)通过依赖注入复用
  • 若需在非控制器代码(如服务层)中复用,可通过 DI 注入配置:
// 1. 注册实例到 DI 容器 
services.AddSingleton(jsonSettings);// 2. 在自定义服务中使用 
public class DataService 
{private readonly JsonSerializerSettings _settings;public DataService(JsonSerializerSettings settings) => _settings = settings;public string SerializeData(object data) => JsonConvert.SerializeObject(data, _settings);
}
http://www.dtcms.com/a/528132.html

相关文章:

  • 网站设计制作电影福建网站建设公司
  • 记录一次Oracle日志listener.log文件大小超过4G后出现Tomcat服务启动一直报错的原因【ORACLE】
  • Docker Desktop快速搭建本地k8s集群
  • LabVIEW超高分辨显微成像系统
  • 东莞建网站的公破解付费wordpress主题
  • 国产数据库破局:金仓数据库如何无缝替代MongoDB支撑2TB政务数据
  • Switch 20.5.0系统最新PSP模拟器懒人包
  • 怎么做网上直营店网站php素材网站源码免费下载
  • 巡检机器人户外视觉识别困境剖析与自动优化模式构建
  • C++ - 异常
  • C++笔记(面向对象)深赋值 浅赋值
  • 数据库在什么情况下会发生数据库死锁
  • 如何将Word文档精确转换为图片型PDF?
  • Auto CAD二次开发——封装事务处理函数并绘制直线函数
  • C4D域力场重要概念之点对象、粒子对象和通道转换
  • 车载诊断架构 ---关于Service 29证书认证与整车时间同步的问题带来的深思
  • 做蛋糕需要建议网站不wordpress跳转移动端模板
  • html5培训网站模板兴国电商网站建设
  • 【JUnit实战3_13】第八章:mock 对象模拟技术在细粒度测试中的应用(上)
  • STM32项目分享:简易自动门设计
  • 小白怎样建设公司网站奔奔网站建设
  • YouTube评论情感分析项目84%正确率:基于BERT的实战复现与原理解析
  • 【Shell】Shell变量
  • 华为OD机考:计算正方形数量(Python C/C++ JAVA JS GO)
  • 基于 STM32 的语音识别智能垃圾桶设计与实现
  • 【基础复习3】决策树
  • 网站设计公司驻马店市住房和城乡建设局网站首页
  • Microsoft AI Genius | 用智能 Microsoft Copilot 副驾驶® 构建高韧性 DevOps 流程
  • wordpress网站布置电子商务网站建设的心得
  • nicegui 无框模式最小化关闭例子