不使用转换器,如何让Person类自行实现System.Text.Json序列化?
在System.Text.Json中让Person类自行实现自定义序列化(无需单独转换器)
.NET 7及以上版本(推荐方案)
.NET 7引入了IJsonSerializable接口,允许类型直接嵌入序列化/反序列化逻辑,无需编写单独的JsonConverter。
实现步骤
- 让
Person类实现IJsonSerializable接口,实现Serialize方法自定义序列化逻辑; - 编写标记
[JsonConstructor]的静态Deserialize方法,处理反序列化逻辑(若需要反序列化)。
示例代码
using System.Text.Json; using System.Text.Json.Serialization; public class Person : IJsonSerializable { public string Name { get; set; } public int Age { get; set; } // 自定义序列化逻辑,直接控制Utf8JsonWriter输出 public void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options) { writer.WriteStartObject(); // 自定义字段名与值,比如将Name映射为FullName,Age翻倍输出 writer.WriteString("FullName", Name); writer.WriteNumber("AgeDouble", Age * 2); writer.WriteEndObject(); } // 自定义反序列化逻辑,标记[JsonConstructor]让System.Text.Json识别 [JsonConstructor] public static Person Deserialize(Utf8JsonReader reader, JsonSerializerOptions options) { var person = new Person(); while (reader.Read()) { if (reader.TokenType == JsonTokenType.EndObject) break; if (reader.TokenType == JsonTokenType.PropertyName) { var propName = reader.GetString(); reader.Read(); switch (propName) { case "FullName": person.Name = reader.GetString(); break; case "AgeDouble": person.Age = reader.GetInt32() / 2; break; } } } return person; } }
使用示例
// 序列化 var person = new Person { Name = "张三", Age = 30 }; string json = JsonSerializer.Serialize(person); // 输出结果:{"FullName":"张三","AgeDouble":60} // 反序列化 var deserializedPerson = JsonSerializer.Deserialize<Person>(json); // deserializedPerson.Name = "张三",deserializedPerson.Age = 30
.NET 6及以下版本(受限方案)
.NET 6及更早版本没有IJsonSerializable接口,无法完全在类内部控制Utf8JsonWriter的输出,但可以通过序列化钩子接口实现部分自定义逻辑:
IJsonOnSerializing:序列化前执行逻辑IJsonOnSerialized:序列化后执行逻辑IJsonOnDeserializing:反序列化前执行逻辑IJsonOnDeserialized:反序列化后执行逻辑
这种方式无法完全自定义JSON结构,只能通过修改类的字段/属性或添加序列化专用成员调整输出。
示例代码
using System.Text.Json.Serialization; public class Person : IJsonOnSerializing { public string Name { get; set; } public int Age { get; set; } // 仅用于序列化的自定义字段,用[JsonInclude]让序列化器识别 [JsonInclude] private string FullName => Name; [JsonInclude] private int AgeDouble => Age * 2; // 序列化前的钩子方法,可在此做预处理 public void OnSerializing() { // 示例:可在此修改属性值(如格式化Name) // Name = $"Mr.{Name}"; } }
注意事项
钩子接口只能辅助调整,无法完全控制JSON生成逻辑;若需要完全自定义,优先推荐升级到.NET 7+版本。
内容的提问来源于stack exchange,提问作者greenoldman
相关产品推荐
相关产品推荐

