VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > c#编程 >
  • JSON序列化/反序列化——用C#演示用户数据持久化

第一部分:C#基础入门
实例13:JSON序列化/反序列化——用户数据持久化
实例介绍
JSON(JavaScript Object Notation) 是一种轻量级、易读易写的文本数据格式,广泛用于数据交换和持久化。序列化是将对象转换为JSON字符串的过程,反序列化则是反向操作——从JSON字符串恢复为对象。
在实际开发中,用户数据持久化是常见场景:比如将用户信息(姓名、邮箱、注册时间等)保存到本地JSON文件,程序下次启动时再读取这些数据,避免每次重新输入。本实例通过System.Text.Json(.NET官方JSON库)实现用户数据的序列化/反序列化,带你掌握JSON操作的核心逻辑,理解持久化的本质。
需求分析
1.定义用户模型:User类包含Id(用户ID)、Name(姓名)、Email(邮箱)、RegistrationTime(注册时间)四个属性;
2.序列化功能:将单个用户对象或用户列表转换为JSON字符串,保存到本地文件;
3.反序列化功能:从JSON文件读取字符串,恢复为用户对象或列表;
4.异常处理:处理文件不存在、JSON格式错误、文件权限不足等异常;
5.测试场景:
1.保存多个用户到users.json文件;
2.从文件读取用户列表,验证数据一致性;
3.模拟JSON格式错误(手动修改文件内容),测试异常捕获。
代码实现
csharp

	using System;
	using System.Collections.Generic;
	using System.IO;
	using System.Text;
	using System.Text.Json;
	
	namespace JsonPersistenceDemo
	{
	// ==================== 1. 用户模型类 ====================
	public class User
	{
	public int Id { get; set; }
	public string Name { get; set; } = string.Empty; // 初始化避免null
	public string Email { get; set; } = string.Empty;
	public DateTime RegistrationTime { get; set; }
	}
	
	// ==================== 2. 数据持久化工具类 ====================
	public static class UserPersistence
	{
	// 序列化选项:缩进格式、自定义日期格式、允许中文
	private static readonly JsonSerializerOptions _serializerOptions = new()
	{
	WriteIndented = true, // 缩进输出(易读)
	DateFormatString = "yyyy-MM-dd HH:mm:ss", // 日期格式
	Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping // 允许中文等特殊字符
	};
	
	/// <summary>
	/// 将对象序列化到JSON文件
	/// </summary>
	public static void SerializeToFile<T>(string filePath, T data)
	{
	try
	{
	// 1. 将对象转为JSON字符串
	string jsonString = JsonSerializer.Serialize(data, _serializerOptions);
	// 2. 写入文件(覆盖模式)
	File.WriteAllText(filePath, jsonString, Encoding.UTF8);
	Console.WriteLine($"✅ 数据已保存到:{filePath}");
	}
	catch (IOException ex)
	{
	Console.WriteLine($"❌ 序列化失败(文件操作错误):{ex.Message}");
	}
	catch (Exception ex)
	{
	Console.WriteLine($"❌ 序列化失败:{ex.Message}");
	}
	}
	
	/// <summary>
	/// 从JSON文件反序列化为对象
	/// </summary>
	public static T? DeserializeFromFile<T>(string filePath)
	{
	try
	{
	// 1. 检查文件是否存在
	if (!File.Exists(filePath))
	{
	Console.WriteLine($"❌ 文件不存在:{filePath}");
	return default;
	}
	// 2. 读取文件内容
	string jsonString = File.ReadAllText(filePath, Encoding.UTF8);
	// 3. 转换为对象
	return JsonSerializer.Deserialize<T>(jsonString, _serializerOptions);
	}
	catch (JsonException ex)
	{
	Console.WriteLine($"❌ 反序列化失败(JSON格式错误):{ex.Message}");
	return default;
	}
	catch (IOException ex)
	{
	Console.WriteLine($"❌ 反序列化失败(文件操作错误):{ex.Message}");
	return default;
	}
	catch (Exception ex)
	{
	Console.WriteLine($"❌ 反序列化失败:{ex.Message}");
	return default;
	}
	}
	}
	
	// ==================== 3. 测试程序 ====================
	class Program
	{
	static void Main(string[] args)
	{
	string filePath = "users.json";
	
	// 步骤1:创建测试用户列表
	var testUsers = new List<User>
	{
	new() { Id = 1, Name = "张三", Email = "zhangsan@example.com", RegistrationTime = DateTime.Now },
	new() { Id = 2, Name = "李四", Email = "lisi@example.com", RegistrationTime = DateTime.Now.AddDays(-1) },
	new() { Id = 3, Name = "王五", Email = "wangwu@example.com", RegistrationTime = DateTime.Now.AddMonths(-1) }
	};
	
	// 步骤2:序列化到文件
	Console.WriteLine("=== 开始序列化 ===");
	UserPersistence.SerializeToFile(filePath, testUsers);
	
	// 步骤3:反序列化从文件
	Console.WriteLine("
=== 开始反序列化 ===");
	var loadedUsers = UserPersistence.DeserializeFromFile<List<User>>(filePath);
	
	// 步骤4:验证结果
	if (loadedUsers != null && loadedUsers.Count > 0)
	{
	Console.WriteLine("
=== 反序列化结果 ===");
	foreach (var user in loadedUsers)
	{
	Console.WriteLine($"ID:{user.Id} | 姓名:{user.Name} | 邮箱:{user.Email} | 注册时间:{user.RegistrationTime}");
	}
	}
	else
	{
	Console.WriteLine("
❌ 未读取到有效用户数据");
	}
	}
	}
	}

逐行讲解

  1. 用户模型类(User)
    csharp
	public class User
	{
	public int Id { get; set; }
	public string Name { get; set; } = string.Empty;
	public string Email { get; set; } = string.Empty;
	public DateTime RegistrationTime { get; set; }
	}

属性设计:包含用户核心信息,string类型初始化= string.Empty避免序列化时出现null(可通过配置选项控制是否忽略null);
无参构造函数:System.Text.Json默认要求类有公共无参构造函数(本类使用C# 9+的记录类简化语法,编译器自动生成无参构造)。
2. 数据持久化工具类(UserPersistence)
序列化选项(_serializerOptions):
csharp

	private static readonly JsonSerializerOptions _serializerOptions = new()
	{
	WriteIndented = true, // 缩进格式(JSON更易读)
	DateFormatString = "yyyy-MM-dd HH:mm:ss", // 自定义日期格式
	Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping // 允许中文/特殊字符(避免转义为Unicode)
	};

WriteIndented:默认false(紧凑格式),设为true后JSON会按层级缩进;
DateFormatString:默认是ISO 8601格式(如2025-12-15T14:30:00),自定义为更直观的yyyy-MM-dd HH:mm:ss;
Encoder:默认会转义非ASCII字符(如中文变为u5F20u4E09),UnsafeRelaxedJsonEscaping可保留原始字符。
SerializeToFile方法:
csharp

	public static void SerializeToFile<T>(string filePath, T data)
	{
	string jsonString = JsonSerializer.Serialize(data, _serializerOptions); // 对象转JSON
	File.WriteAllText(filePath, jsonString, Encoding.UTF8); // 写入文件
	}

泛型:支持任意类型(单个User或List均可);
File.WriteAllText:覆盖写入文件(若需追加,需手动读取原有内容合并后再写入)。
DeserializeFromFile方法:
csharp

	public static T? DeserializeFromFile<T>(string filePath)
	{
	if (!File.Exists(filePath)) return default; // 文件不存在返回默认值
	string jsonString = File.ReadAllText(filePath, Encoding.UTF8); // 读文件
	return JsonSerializer.Deserialize<T>(jsonString, _serializerOptions); // JSON转对象
	}

T?:C# 8+的可空类型(若T是引用类型,允许返回null);
JsonException:当JSON格式错误(如缺少括号、字段类型不匹配)时抛出,需单独捕获。
3. 测试程序
csharp

	var testUsers = new List<User> { new User(1, "张三", ...), ... }; // 创建测试数据
	UserPersistence.SerializeToFile(filePath, testUsers); // 保存到文件
	var loadedUsers = UserPersistence.DeserializeFromFile<List<User>>(filePath); // 读取
	foreach (var user in loadedUsers) Console.WriteLine(...) // 验证结果

测试流程:创建数据→序列化→反序列化→对比结果,确保数据一致性;
若手动修改users.json的内容(如删除某个括号),反序列化时会抛出JsonException,验证异常处理逻辑。
基础知识拓展

  1. JSON核心概念
    键值对:JSON基本单位(如"Name": "张三");
    数组:用[]包裹多个对象(如[{"Id":1}, {"Id":2}]);
    嵌套对象:对象内部包含其他对象(如"Address": {"City": "北京", "Street": "长安街"})。
  2. System.Text.Json核心组件
组件名 作用
JsonSerializer 静态类,提供Serialize(对象转JSON)和Deserialize(JSON转对象)方法
JsonSerializerOptions 配置序列化/反序列化规则(缩进、日期格式、忽略null等)
JsonPropertyNameAttribute 自定义JSON字段名(如[JsonPropertyName("user_id")]将Id转为user_id)
JsonIgnoreAttribute 忽略某个属性(如[JsonIgnore]标记Password字段不序列化)
  1. System.Text.Json vs Newtonsoft.Json
特性 System.Text.Json(微软官方) Newtonsoft.Json(第三方)
性能 更高(原生实现,无反射) 略低(依赖反射)
体积 更小(内置到.NET Core) 需额外引用包
功能丰富度 基础功能齐全,高级功能少 功能强大(支持动态类型、LINQ)
兼容性 .NET Core 3.0+支持 支持所有.NET版本

选择建议:新项目优先用System.Text.Json(性能好、无依赖);若需复杂功能(如动态JSON处理),再考虑Newtonsoft.Json。
4. 持久化的其他方式

方式 优点 缺点
JSON文件 轻量、易读、跨平台 不适合大量数据(查询慢)
XML文件 结构严谨、支持Schema验证 冗余度高、体积大
SQLite数据库 支持结构化查询、事务、索引 需学习SQL语法
二进制序列化 体积小、速度快 不跨平台、可读性差

扩展思考

如何自定义JSON字段名?
给User类的属性加[JsonPropertyName]特性:

csharp

	public class User
	{
	[JsonPropertyName("user_id")]
	public int Id { get; set; }
	}

序列化后Id会变为"user_id"。

如何忽略敏感属性?
给Password属性加[JsonIgnore]特性:

csharp

	[JsonIgnore]
	public string Password { get; set; } = string.Empty;

序列化时不会包含Password字段。

如何处理版本兼容?
若User类新增Age字段,旧JSON文件中无此字段,可通过JsonSerializerOptions设置默认值:

csharp

	options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; // 忽略null值
	options.MissingMemberHandling = JsonMissingMemberHandling.Ignore; // 忽略JSON中不存在的属性
INI 复制 全屏

如何异步序列化/反序列化? 使用异步文件操作方法:

csharp

	public static async Task SerializeToFileAsync<T>(string filePath, T data)
	{
	string json = JsonSerializer.Serialize(data, _serializerOptions);
	await File.WriteAllTextAsync(filePath, json, Encoding.UTF8);
	}

总结
JSON序列化/反序列化是数据持久化的基础技术,通过System.Text.Json可快速实现对象与文件的转换。本实例的核心是掌握JsonSerializer的使用和JsonSerializerOptions的配置,同时需注意异常处理和数据安全(如敏感数据需加密后再序列化)。
在实际项目中,JSON不仅用于本地文件持久化,还广泛用于API接口数据交换(如前后端通信、微服务调用),是后端开发必备技能之一。

本站原创,转载请注明出处:https://www.xin3721.com/ArticlecSharp/c49415.html


相关教程