如何用System.Text.Json将JSON字符串属性反序列化为自定义C#对象
解决方案:使用System.Text.Json自定义转换器
直接通过自定义Json转换器就能实现反序列化时自动将CSV字符串转为CSV对象,无需反射,也能保持代码的整洁性。
1. 实现CSV类型的自定义转换器
创建继承JsonConverter<CSV>的转换器类,在Read方法中处理字符串解析逻辑,自动映射到CSV对象的属性,缺失的属性会使用类型默认值:
public class CSVConverter : JsonConverter<CSV> { public override CSV Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var csvString = reader.GetString(); var csvObj = new CSV(); if (string.IsNullOrEmpty(csvString)) return csvObj; // 分割键值对并遍历处理 var keyValuePairs = csvString.Split(',', StringSplitOptions.RemoveEmptyEntries); foreach (var kvp in keyValuePairs) { var parts = kvp.Split(':', 2); if (parts.Length != 2) continue; var propertyName = parts[0].Trim().ToUpperFirstLetter(); var valueStr = parts[1].Trim(); // 找到对应属性并赋值 var property = typeof(CSV).GetProperty(propertyName); if (property == null) continue; try { var parsedValue = Convert.ChangeType(valueStr, property.PropertyType); property.SetValue(csvObj, parsedValue); } catch { /* 解析失败时保留默认值 */ } } return csvObj; } // 可选:实现序列化逻辑,将CSV对象转回字符串格式 public override void Write(Utf8JsonWriter writer, CSV value, JsonSerializerOptions options) { var propertyKvps = typeof(CSV).GetProperties() .Select(p => $"{p.Name.ToLower()}:{p.GetValue(value)}"); writer.WriteStringValue(string.Join(',', propertyKvps)); } } // 辅助扩展方法:将字符串首字母大写 public static string ToUpperFirstLetter(this string input) { if (string.IsNullOrEmpty(input)) return input; return char.ToUpper(input[0]) + input.Substring(1); }
2. 修改实体类定义
将MyJsonData中的Csv属性类型改为CSV,并标记转换器特性(或在序列化选项中全局添加):
public class MyJsonData { public int Version { get; set; } public string Guid { get; set; } // 标记使用自定义转换器 [JsonConverter(typeof(CSVConverter))] public CSV Csv { get; set; } public string Method { get; set; } } public class CSV { public int One { get; set; } public bool Two { get; set; } public int Three { get; set; } }
3. 执行反序列化
直接调用JsonSerializer.Deserialize即可,转换器会自动处理CSV字符串的解析:
var json = @" { ""version"": 0, ""guid"": ""2166a7d5744d47009adaa29f0e549696"", ""csv"": ""one:1,two:2,three:3"", ""method"": ""substract"" }"; var data = JsonSerializer.Deserialize<MyJsonData>(json); // 直接访问解析后的对象 Console.WriteLine(data.Csv.One); // 输出1 Console.WriteLine(data.Csv.Two); // 输出True
可选:全局配置转换器
如果不想在属性上标记特性,可以在序列化选项中全局添加转换器:
var options = new JsonSerializerOptions(); options.Converters.Add(new CSVConverter()); var data = JsonSerializer.Deserialize<MyJsonData>(json, options);
内容的提问来源于stack exchange,提问作者notarobot
相关产品推荐
相关产品推荐

