.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字段加入序列化列表:
- 实现自定义解析器:
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; } }
- 使用该解析器序列化:
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
相关产品推荐
相关产品推荐

