using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Serialization; namespace SHH.CameraService { /// /// JSON 序列化与反序列化帮助类 /// 职责: /// 1. 提供全局统一的 JSON 转换配置(如驼峰命名、日期格式)。 /// 2. 封装常见的序列化和反序列化操作。 /// 3. 增加对 null 输入和无效 JSON 的健壮性处理。 /// public static class JsonHelper { #region --- 静态配置 --- /// /// 全局共享的 JSON 序列化设置。 /// 静态构造函数保证其只被初始化一次。 /// private static readonly JsonSerializerSettings _settings; #endregion #region --- 静态构造函数 --- /// /// 静态构造函数,用于初始化全局的 JSON 序列化设置。 /// static JsonHelper() { _settings = new JsonSerializerSettings { // 1. 命名策略:将 C# 的 PascalCase 属性名序列化为 JSON 的 camelCase。 // 这是与 JavaScript/TypeScript 前端交互的标准做法。 ContractResolver = new CamelCasePropertyNamesContractResolver(), // 2. 日期格式:统一使用 "yyyy-MM-dd HH:mm:ss" 格式,避免时区和格式差异导致的问题。 DateFormatString = "yyyy-MM-dd HH:mm:ss", // 3. Null 值处理:在序列化时忽略值为 null 的属性。 // 这可以显著减小 JSON 字符串的大小,并使生成的 JSON 更干净。 // 例如,`{ Name = "Alice", Age = null }` 会被序列化为 `{"name":"Alice"}`。 NullValueHandling = NullValueHandling.Ignore }; // 4. 枚举转换:将枚举值序列化为其字符串表示,而不是数字。 // 例如,`LogLevel.Info` 会被序列化为 `"info"`,而不是 `1`。 _settings.Converters.Add(new StringEnumConverter()); } #endregion #region --- 公共方法 --- /// /// 将对象序列化为 JSON 字符串。 /// /// 要序列化的对象。 /// 序列化后的 JSON 字符串。如果输入为 null,则返回空字符串。 public static string Serialize(object obj) { // [健壮性] 如果输入对象为 null,返回空字符串,而不是 "null"。 // 这可以防止在创建 HTTP 请求内容时出现意外行为。 if (obj == null) { return string.Empty; } return JsonConvert.SerializeObject(obj, _settings); } /// /// 将 JSON 字符串反序列化为指定类型的对象。 /// /// 目标对象的类型(必须是引用类型)。 /// 要反序列化的 JSON 字符串。 /// 成功时返回反序列化后的对象;失败或输入无效时返回 null。 public static T? Deserialize(string json) where T : class { // [健壮性] 检查输入是否为 null、空字符串或仅包含空白字符。 if (string.IsNullOrWhiteSpace(json)) { return null; } // [健壮性] 处理 JSON 字符串为 "null" 的特殊情况。 if (json.Trim() == "null") { return null; } try { // 尝试使用预配置的设置进行反序列化。 return JsonConvert.DeserializeObject(json, _settings); } catch (JsonException) { // [健壮性] 如果 JSON 格式无效,捕获异常并返回 null。 // 这可以防止程序因一个格式错误的 JSON 字符串而崩溃。 return null; } } #endregion } }