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

ASP.NET Core Web API返回继承类实例列表时序列化丢失属性的解决方法

解决ASP.NET Core Web API返回多态对象数组时丢失子类属性的问题

这个问题太常见了——默认的JSON序列化器(现在ASP.NET Core原生用的是System.Text.Json)不会自动处理多态类型的序列化逻辑,所以当你返回List<MainClass>时,它只会序列化基类MainClass的属性,ClassA和ClassB的专属字段直接被忽略了。下面给你两种实用的解决方案:

方案1:用原生System.Text.Json开启多态支持

方式A:给基类加特性标记

直接在你的基类MainClass上添加[JsonDerivedType]特性,明确告诉序列化器要处理哪些派生类:

using System.Text.Json.Serialization;

// 标记派生类,第二个参数是类型判别符(序列化时会自动添加这个字段区分类型)
[JsonDerivedType(typeof(ClassA), typeDiscriminator: "class_a")]
[JsonDerivedType(typeof(ClassB), typeDiscriminator: "class_b")]
public class MainClass
{
    public int Id { get; set; }
    public string BaseCommonProperty { get; set; }
}

public class ClassA : MainClass
{
    public string ExclusivePropertyForA { get; set; }
}

public class ClassB : MainClass
{
    public int ExclusivePropertyForB { get; set; }
}

这样配置后,当你在控制器返回List<MainClass>时,序列化器会自动包含子类的专属属性,同时会带上你指定的类型判别字段,方便前端或者消费方区分不同类型。

方式B:全局配置派生类型

如果不想修改实体类的代码,可以在Program.cs的服务配置里全局设置:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        // 给MainClass添加派生类型支持
        options.JsonSerializerOptions.TypeInfoResolverChain.Add(
            JsonSerializerOptions.Default.GetTypeInfo(typeof(MainClass))
                .WithDerivedTypes(typeof(ClassA), typeof(ClassB))
        );
    });

这种方式更适合不能修改实体类源码的场景。

方案2:切换到Newtonsoft.Json(Json.NET)

如果你习惯用Json.NET,或者需要更灵活的多态处理逻辑,可以切换到它:

  1. 先安装NuGet包:Microsoft.AspNetCore.Mvc.NewtonsoftJson
  2. 在Program.cs中配置服务:
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .AddNewtonsoftJson(options =>
    {
        // 自动处理多态类型,序列化时会添加$type字段标记具体类型
        options.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto;
    });

配置完成后,返回List<MainClass>时,Json.NET会自动序列化所有子类的专属属性,不需要额外给基类加标记。

验证示例(控制器代码)

最后给你一个控制器的示例,测试下效果:

[ApiController]
[Route("api/polymorphic")]
public class PolymorphicController : ControllerBase
{
    [HttpGet]
    public ActionResult<List<MainClass>> GetItems()
    {
        var items = new List<MainClass>
        {
            new ClassA { Id = 1, BaseCommonProperty = "来自A的基础属性", ExclusivePropertyForA = "只有A才有的字符串" },
            new ClassB { Id = 2, BaseCommonProperty = "来自B的基础属性", ExclusivePropertyForB = 12345 }
        };
        return Ok(items);
    }
}

现在调用这个接口,就能得到包含所有子类专属属性的JSON响应了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:33:43