如何用Newtonsoft.Json自定义序列化生成指定JSON结构
实现自定义C#类到指定JSON格式的序列化
针对你的需求,我们可以通过自定义JSON转换器来实现FaactRecordDifferences类到目标JSON格式的序列化,下面分别介绍两种主流JSON库的实现方案:
方案一:使用Newtonsoft.Json(Json.NET)
Newtonsoft.Json的自定义转换器API灵活易用,适合快速实现复杂序列化逻辑。
1. 编写自定义转换器
创建针对List<FieldDifference>的转换器,将列表转换为JSON键值对,并根据type字段处理值的类型:
using Newtonsoft.Json; using System; using System.Collections.Generic; public class FieldDifferenceListConverter : JsonConverter<List<FieldDifference>> { public override void WriteJson(JsonWriter writer, List<FieldDifference> value, JsonSerializer serializer) { writer.WriteStartObject(); foreach (var field in value) { writer.WritePropertyName(field.FieldName); // 根据类型决定序列化方式 if (field.type == typeof(string)) { writer.WriteValue(field.FieldValue); } else { // 将字符串值转换为目标类型后序列化 var convertedValue = Convert.ChangeType(field.FieldValue, field.type); writer.WriteValue(convertedValue); } } writer.WriteEndObject(); } public override List<FieldDifference> ReadJson(JsonReader reader, Type objectType, List<FieldDifference> existingValue, bool hasExistingValue, JsonSerializer serializer) { // 若需反序列化可在此实现,示例暂不提供 throw new NotImplementedException("反序列化逻辑未实现"); } }
2. 标记需要转换的属性
在FaactRecordDifferences类的Fields属性上添加转换器标记:
public class FaactRecordDifferences { public string Id { get; set; } public int Year { get; set; } [JsonConverter(typeof(FieldDifferenceListConverter))] public List<FieldDifference> Fields { get; set; } } public class FieldDifference { public string FieldName { get; set; } public string FieldValue { get; set; } public Type type { get; set; } }
3. 序列化示例
var record = new FaactRecordDifferences { Id = "U123321", Year = 2024, Fields = new List<FieldDifference> { new() { FieldName = "SomeFirstField", FieldValue = "1200.21", type = typeof(double) }, new() { FieldName = "AnotherTestField", FieldValue = "SomeStringValue", type = typeof(string) }, new() { FieldName = "SomethingHere", FieldValue = "6120.40", type = typeof(double) } } }; var json = JsonConvert.SerializeObject(record, Formatting.Indented); Console.WriteLine(json);
方案二:使用System.Text.Json(.NET Core/.NET 5+ 默认库)
如果使用.NET官方的System.Text.Json,同样可以通过自定义转换器实现需求:
1. 编写自定义转换器
using System; using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Serialization; public class FieldDifferenceListConverter : JsonConverter<List<FieldDifference>> { public override List<FieldDifference> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // 若需反序列化可在此实现,示例暂不提供 throw new NotImplementedException("反序列化逻辑未实现"); } public override void Write(Utf8JsonWriter writer, List<FieldDifference> value, JsonSerializerOptions options) { writer.WriteStartObject(); foreach (var field in value) { writer.WritePropertyName(field.FieldName); if (field.type == typeof(string)) { writer.WriteStringValue(field.FieldValue); } else { // 转换类型后序列化 var convertedValue = Convert.ChangeType(field.FieldValue, field.type); JsonSerializer.Serialize(writer, convertedValue, field.type, options); } } writer.WriteEndObject(); } }
2. 应用转换器
可以通过属性标记或序列化选项两种方式应用转换器:
- 属性标记方式:和Newtonsoft.Json一样,在
Fields属性上添加[JsonConverter(typeof(FieldDifferenceListConverter))] - 序列化选项方式:
var options = new JsonSerializerOptions { Converters = { new FieldDifferenceListConverter() }, WriteIndented = true // 格式化输出 }; var json = JsonSerializer.Serialize(record, options); Console.WriteLine(json);
注意事项
FieldValue的字符串必须能正确转换为指定的type,否则会抛出转换异常,建议添加try-catch或提前验证值的格式。- 若需要支持特殊类型(如
DateTime、Guid),可以在转换器中单独处理这些类型的转换逻辑。 - 如果需要反序列化功能,需补充实现转换器中的
Read方法,将JSON键值对转换回List<FieldDifference>。
内容的提问来源于stack exchange,提问作者GregH
相关产品推荐
相关产品推荐

