You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不使用转换器,如何让Person类自行实现System.Text.Json序列化?

在System.Text.Json中让Person类自行实现自定义序列化(无需单独转换器)

.NET 7及以上版本(推荐方案)

.NET 7引入了IJsonSerializable接口,允许类型直接嵌入序列化/反序列化逻辑,无需编写单独的JsonConverter。

实现步骤

  1. 让Person类实现IJsonSerializable接口,实现Serialize方法自定义序列化逻辑;
  2. 编写标记[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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 21:50:22