使用System.Text.Json反序列化JSON到基类时Command为空的问题
问题解决:反序列化BaseRequest时Command为空的原因与修复方法
问题根源
BaseRequest中的Command是只读属性(仅包含get访问器),而System.Text.Json默认不会将JSON中的值反序列化到只读属性中,因此反序列化后obj.Command始终是初始化的空字符串,导致判断逻辑失效。
修复方案
方案1:给BaseRequest的Command添加私有setter
修改BaseRequest的定义,为Command添加私有setter,既保留外部只读特性,又允许序列化器写入属性值:
public class BaseRequest : IRequest { public string Command { get; private set; } = ""; }
修改后执行原有代码,即可正确获取JSON中的Command值。
方案2:用JsonInclude特性强制序列化只读属性
如果不想修改属性的访问器,可以给Command标记[JsonInclude]特性,告知序列化器处理该只读属性:
using System.Text.Json.Serialization; public class BaseRequest : IRequest { [JsonInclude] public string Command { get; } = ""; }
此方案无需调整权限,仅通过特性实现序列化支持。
方案3:使用多态反序列化一步到位
若想优化代码逻辑,避免两次反序列化,可以配置多态反序列化,让序列化器根据Command值自动实例化对应的子类:
using System.Text.Json; using System.Text.Json.Serialization; // 配置多态序列化选项 var options = new JsonSerializerOptions { TypeInfoResolver = new DefaultJsonTypeInfoResolver { Modifiers = { typeInfo => { if (typeInfo.Type == typeof(IRequest)) { typeInfo.PolymorphismOptions = new JsonPolymorphismOptions { // 指定JSON中的"Command"字段作为类型判别依据 TypeDiscriminatorPropertyName = "Command", IgnoreUnrecognizedTypeDiscriminators = true, // 映射Command值到对应子类 DerivedTypes = { new JsonDerivedType(typeof(GetRequest), "get"), new JsonDerivedType(typeof(SetRequest), "set") } }; } } } } }; // 直接反序列化为IRequest,自动匹配对应的子类 var request = JsonSerializer.Deserialize<IRequest>(jsonData, options); // 用模式匹配处理不同请求类型 switch (request) { case GetRequest getReq: Console.WriteLine($"处理Get请求,Key: {getReq.Key}"); // 执行Get逻辑 break; case SetRequest setReq: Console.WriteLine($"处理Set请求,Key: {setReq.Key},Value: {setReq.Value}"); // 执行Set逻辑 break; default: Console.WriteLine("Unknown command"); break; }
这种方式无需先反序列化基类再判断,代码更简洁高效。
内容的提问来源于stack exchange,提问作者VerySimple
相关产品推荐
相关产品推荐

