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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 23:05:23