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

如何在JSON属性前添加注释?基于.NET特性实现配置文件注释输出

问题描述

我希望将JSON作为程序配置文件格式,写入磁盘时要包含每个字段的描述注释,且尽量通过特性来控制这些注释。现有C#类定义如下:

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

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

期望输出的JSON格式如下:

{
  /*Name of the person*/
  "Name": "Jack",
  /*Age of the person*/
  "Age": 22
}

此前相关问题大多介绍如何在值后添加注释(例如在"Jack"后),而我需要在属性名前添加注释(例如在"Name"前)。请问使用Json.NET、System.Text.Json或其他库能否实现这种注释格式?

解决方案

使用Json.NET(Newtonsoft.Json)实现

Json.NET本身不直接支持属性前置注释,但可以通过重写JsonTextWriter来精准控制注释输出位置:

  1. 先定义自定义特性(如果未定义):
public class JsonCommentAttribute : Attribute
{
    public string Comment { get; }

    public JsonCommentAttribute(string comment)
    {
        Comment = comment;
    }
}
  1. 重写JsonTextWriter,在写入属性名前检查特性并输出注释:
public class CommentedJsonTextWriter : JsonTextWriter
{
    private readonly Type _targetType;

    public CommentedJsonTextWriter(TextWriter writer, Type targetType) : base(writer)
    {
        _targetType = targetType;
        Formatting = Formatting.Indented;
    }

    public override void WritePropertyName(string name)
    {
        var property = _targetType.GetProperty(name);
        if (property != null)
        {
            var commentAttr = property.GetCustomAttribute<JsonCommentAttribute>();
            if (commentAttr != null)
            {
                WriteIndent();
                WriteRaw($"/*{commentAttr.Comment}*/");
                WriteNewLine();
            }
        }
        base.WritePropertyName(name);
    }
}
  1. 序列化时使用自定义写入器:
var person = new Person { Name = "Jack", Age = 22 };
using var stringWriter = new StringWriter();
using var writer = new CommentedJsonTextWriter(stringWriter, typeof(Person));
new JsonSerializer().Serialize(writer, person);
var json = stringWriter.ToString();

使用System.Text.Json实现

System.Text.Json默认也不支持前置注释,可通过自定义JsonConverter实现:

  1. 同样先定义JsonCommentAttribute(代码同Json.NET部分)。

  2. 创建自定义对象转换器:

public class CommentedObjectConverter<T> : JsonConverter<T>
{
    public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return JsonSerializer.Deserialize<T>(ref reader, options);
    }

    public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
    {
        writer.WriteStartObject();
        var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
        
        foreach (var prop in properties)
        {
            var commentAttr = prop.GetCustomAttribute<JsonCommentAttribute>();
            if (commentAttr != null)
            {
                // 输出/* */格式注释,需手动处理缩进换行
                writer.WriteRawValue($"/*{commentAttr.Comment}*/");
                writer.WriteRawValue(Environment.NewLine);
            }
            
            var propValue = prop.GetValue(value);
            writer.WritePropertyName(prop.Name);
            JsonSerializer.Serialize(writer, propValue, prop.PropertyType, options);
        }
        
        writer.WriteEndObject();
    }
}
  1. 配置转换器并序列化:
var options = new JsonSerializerOptions
{
    WriteIndented = true,
    Converters = { new CommentedObjectConverter<Person>() }
};
var json = JsonSerializer.Serialize(new Person { Name = "Jack", Age = 22 }, options);

其他可选方案

  • 小众库如JsonFx支持自定义注释输出,但生态成熟度远不如Json.NET和System.Text.Json;
  • 若需结合JSON Schema生成注释,可使用JsonSchema.Net.Generation,但仅用于配置文件生成的话会显得冗余。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 21:54:53