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

ASP.NET Core中返回Container对象时子类属性丢失的原因解析

问题:ASP.NET Core接口返回JSON时子类属性丢失的原因

代码定义

数据类

public class BaseData
{
    public string BaseDataStuff { get; set; }
}

public class ChildData : BaseData
{
    public string ChildDataStuff { get; set; }
}

容器类

public class Container
{
    public BaseData Data { get; set; }
}

ASP.NET Core控制器

public class Controller : ControllerBase
{
    private readonly ChildData Data;
    private readonly Container Container;
    public Controller()
    {
        Data = new ChildData()
        {
            BaseDataStuff = "base stuff",
            ChildDataStuff = "child stuff"
        };

        Container = new Container()
        {
            Data = Data
        };
    }


    [HttpGet("data")]
    public ActionResult<BaseData> GetData() => Ok(Container.Data);

    [HttpGet("container")]
    public ActionResult<Container> GetContainer() => Ok(Container);

}

现象

  • 调用/data接口,返回JSON包含子类全部属性:
{
  "childDataStuff": "child stuff",
  "baseDataStuff": "base stuff"
}
  • 调用/container接口,返回JSON仅包含父类属性,子类属性丢失:
{
  "data": {
    "baseDataStuff": "base stuff"
    }
}

原因

这是因为ASP.NET Core默认使用的System.Text.Json序列化器,处理嵌套对象时会**依据属性的声明类型(这里是BaseData)**来序列化,而非实例的实际运行时类型(ChildData)。

  • 对于GetData接口,直接返回的是实例本身,序列化器能直接获取到它的运行时类型ChildData,因此会序列化所有属性。
  • 对于GetContainer接口,序列化的是Container对象,其中Data属性的声明类型为BaseData,序列化器只会序列化BaseData中定义的属性,自动忽略子类的额外属性。

解决方法

方法1:给父类添加派生类型标记

在BaseData类上添加[JsonDerivedType]特性,明确告知序列化器需要处理的子类:

[JsonDerivedType(typeof(ChildData))]
public class BaseData
{
    public string BaseDataStuff { get; set; }
}

方法2:全局配置多态序列化(.NET 7+)

在Program.cs中配置JsonOptions,开启指定类型的多态处理:

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.TypeInfoResolverChain.Insert(0, 
            new DefaultJsonTypeInfoResolver
            {
                Modifiers = { typeInfo =>
                    {
                        if (typeInfo.Type == typeof(BaseData))
                        {
                            typeInfo.PolymorphismOptions = new JsonPolymorphismOptions
                            {
                                DerivedTypes = { new JsonDerivedType(typeof(ChildData)) }
                            };
                        }
                    }
                }
            });
    });

方法3:替换为Newtonsoft.Json(Json.NET)

Newtonsoft.Json默认会识别实例的运行时类型并序列化全部属性。先安装包:

Install-Package Microsoft.AspNetCore.Mvc.NewtonsoftJson

然后在Program.cs中配置:

builder.Services.AddControllers().AddNewtonsoftJson();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 06:15:29