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

.NET 7中如何使用System.Text.Json序列化const常量?

解决System.Text.Json序列化const常量的问题

核心原因

System.Text.Json 默认只会序列化实例成员,而const是编译时常量,属于静态成员范畴,所以默认不会被纳入序列化逻辑——这也是你添加[JsonIgnore(Condition = JsonIgnoreCondition.Never)]无效的原因,这个特性只对实例成员生效。

解决方案

方案1:用实例属性包装const常量(快速简单)

给每个命令类新增一个返回const值的实例属性,并用[JsonPropertyName]指定序列化后的字段名,让System.Text.Json识别并序列化:

public class CreateResourceCommand : BaseCommand
{
    public const string CommandName = "CreateResourceCommand";

    // 包装常量的实例属性,指定JSON字段名
    [JsonPropertyName("CommandName")]
    public string CommandNameValue => CommandName;

    // 其他命令属性
    public string ResourceName { get; set; }
}

序列化后生成的JSON会包含"CommandName": "CreateResourceCommand"字段。

方案2:自定义类型信息解析器(批量处理所有命令类)

如果有大量命令类,不想逐个添加包装属性,可以自定义JsonTypeInfoResolver,让它自动识别并把const字段加入序列化列表:

  1. 实现自定义解析器:
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;

public class IncludeConstFieldsResolver : DefaultJsonTypeInfoResolver
{
    public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options)
    {
        var typeInfo = base.GetTypeInfo(type, options);
        
        // 遍历所有公共静态const字段(含父类继承的)
        var constFields = type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
                              .Where(f => f.IsLiteral && !f.IsInitOnly); // IsLiteral标记const,IsInitOnly对应readonly字段

        foreach (var field in constFields)
        {
            // 创建对应JsonPropertyInfo
            var propertyInfo = options.MakeReadOnlyProperty(typeInfo, field.Name, field.FieldType);
            // 静态字段直接取null作为实例参数取值
            propertyInfo.Get = static (obj) => field.GetValue(null);
            // const不可修改,Set逻辑留空
            propertyInfo.Set = static (obj, value) => { };
            propertyInfo.IsReadOnly = true;
            // 保持JSON字段名和const字段名一致
            propertyInfo.JsonPropertyName = field.Name;
            
            typeInfo.Properties.Add(propertyInfo);
        }

        return typeInfo;
    }
}
  1. 使用该解析器序列化:
var serializerOptions = new JsonSerializerOptions
{
    TypeInfoResolver = new IncludeConstFieldsResolver(),
    // 可添加其他配置,比如驼峰命名
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};

var command = new CreateResourceCommand { ResourceName = "TestResource" };
var json = JsonSerializer.Serialize(command, serializerOptions);

这个方案会自动序列化所有命令类(包括BaseCommand中的const),无需逐个修改类定义。

注意事项

  • 方案2中要确保const字段的类型是System.Text.Json支持序列化的类型(如string、int等),特殊类型需额外处理转换逻辑。
  • 反序列化时,const是只读属性,不会影响反序列化流程,消费者可直接读取JSON中的CommandName字段值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 02:06:18