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

.NET 4.8下用System.Text.Json序列化JSON时如何添加注释?

在System.Text.Json中为JSON序列化添加字段注释(.NET 4.8 + v9.0)

你提到的Newtonsoft.Json自定义转换器传参的方案,在System.Text.Json中行不通,因为它的JsonConverterAttribute不支持通过属性参数向转换器传递值。要实现值后追加/*注释内容*/的序列化效果,可以按以下步骤实现:

1. 定义注释属性

先创建一个自定义属性,用来标记每个字段的注释内容:

[AttributeUsage(AttributeTargets.Property)]
public class JsonPropertyCommentAttribute : Attribute
{
    public string Comment { get; }

    public JsonPropertyCommentAttribute(string comment)
    {
        Comment = comment;
    }
}

2. 自定义JSON写入器

继承Utf8JsonWriter,重写值写入方法,在写完值后追加注释:

public class CommentJsonWriter : Utf8JsonWriter
{
    private string _currentPropertyComment;

    public CommentJsonWriter(Stream stream, JsonWriterOptions options)
        : base(stream, options)
    {
    }

    public void SetCurrentPropertyComment(string comment)
    {
        _currentPropertyComment = comment;
    }

    public override void WriteStringValue(string value)
    {
        base.WriteStringValue(value);
        AppendComment();
    }

    public override void WriteNumberValue(int value)
    {
        base.WriteNumberValue(value);
        AppendComment();
    }

    // 按需重写其他值类型的Write方法,比如long、bool、double等
    public override void WriteNumberValue(long value)
    {
        base.WriteNumberValue(value);
        AppendComment();
    }

    public override void WriteBooleanValue(bool value)
    {
        base.WriteBooleanValue(value);
        AppendComment();
    }

    private void AppendComment()
    {
        if (!string.IsNullOrWhiteSpace(_currentPropertyComment))
        {
            WriteRawValue($"/*{_currentPropertyComment}*/");
            _currentPropertyComment = null;
        }
    }
}

3. 实现通用实体转换器

创建一个通用转换器,通过反射读取属性上的注释,配合自定义写入器完成序列化:

public class CommentConverter<T> : JsonConverter<T> where T : class, new()
{
    public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // 反序列化时忽略注释,使用默认逻辑
        options.ReadCommentHandling = JsonCommentHandling.Skip;
        return JsonSerializer.Deserialize<T>(ref reader, options);
    }

    public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
    {
        var commentWriter = writer as CommentJsonWriter;
        if (commentWriter == null)
        {
            JsonSerializer.Serialize(writer, value, options);
            return;
        }

        commentWriter.WriteStartObject();
        var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

        foreach (var prop in properties)
        {
            var commentAttr = prop.GetCustomAttribute<JsonPropertyCommentAttribute>();
            var propValue = prop.GetValue(value);

            commentWriter.WritePropertyName(prop.Name);
            commentWriter.SetCurrentPropertyComment(commentAttr?.Comment);

            // 根据属性类型写入值,这里可以扩展更多类型
            if (prop.PropertyType == typeof(string))
            {
                commentWriter.WriteStringValue(propValue as string);
            }
            else if (prop.PropertyType == typeof(int))
            {
                commentWriter.WriteNumberValue((int)propValue);
            }
            else if (prop.PropertyType == typeof(long))
            {
                commentWriter.WriteNumberValue((long)propValue);
            }
            else if (prop.PropertyType == typeof(bool))
            {
                commentWriter.WriteBooleanValue((bool)propValue);
            }
            // 其他类型可自行扩展
        }

        commentWriter.WriteEndObject();
    }
}

4. 标记实体类属性

用自定义注释属性标记需要添加注释的字段:

public class Person
{
    [JsonPropertyComment("Name of the person")]
    public string Name { get; set; }

    [JsonPropertyComment("Age of the person")]
    public int Age { get; set; }
}

5. 序列化调用示例

var person = new Person { Name = "Jack", Age = 22 };

using var stream = new MemoryStream();
var writerOptions = new JsonWriterOptions { Indented = true };

using var commentWriter = new CommentJsonWriter(stream, writerOptions);
var serializerOptions = new JsonSerializerOptions();
serializerOptions.Converters.Add(new CommentConverter<Person>());

JsonSerializer.Serialize(commentWriter, person, serializerOptions);

stream.Position = 0;
using var reader = new StreamReader(stream);
var resultJson = reader.ReadToEnd();
Console.WriteLine(resultJson);

注意事项

  • 生成的JSON包含注释,不符合JSON标准,反序列化时需设置JsonSerializerOptions.ReadCommentHandling = JsonCommentHandling.Skip来忽略注释
  • 通用转换器目前只实现了常见类型,可根据实际需求扩展更多数据类型的写入逻辑
  • 如果需要支持嵌套实体,需在转换器中递归处理嵌套属性

内容的提问来源于stack exchange,提问作者user1797147

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 11:50:18