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

.NET 5控制器返回含子类属性的基类列表方法咨询

问题:.NET 5控制器返回基类对象列表时如何保留子类属性?

在.NET 5控制器中返回包含子类属性的基类对象列表时,JSON结果中无法看到派生类属性,但将List<StepBaseDto>改为List<object>或dynamic可正常显示。现有代码定义如下:

基类与派生类Dto:

public class StepBaseDto 
{
    public string Title { get; set; }
    public int Order { get; set; }
    public StepType StepType { get; set; }
    public bool IsDone { get; set; }
    public string Description { get; set; }
    public string PropertyLabel { get; protected set; }
    public Guid ProtocolId { get; set; }
    public List<SubStepDto> SubSteps { get; set; }
}

public class StartDateStepDto : StepBaseDto
{
    public DateTime? StartingDate { get; set; }
}

public class ProtocolDto : ProtocolBaseDto
{
    public List<StepBaseDto> StepSequence { get; set; }
}

端点定义:

public override Task<ProtocolDto> GetAsync(Guid id)

基于ABP框架5.3.4和Automapper,希望找到无需替换基类为object或dynamic的解决方案。


解决方案

1. 配置System.Text.Json支持多态序列化

.NET 5默认使用System.Text.Json,默认不会序列化基类集合中的派生类属性,需显式配置多态类型信息。

方式一:通过特性标记基类

直接在基类StepBaseDto上添加JsonDerivedType特性,指定所有派生类:

[JsonDerivedType(typeof(StartDateStepDto), typeDiscriminator: "StartDate")]
// 如有其他派生类,继续添加[JsonDerivedType]特性
public class StepBaseDto 
{
    // 原有属性定义
}

方式二:在服务配置中全局设置

在Startup.cs的ConfigureServices方法中配置Json序列化选项:

services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver
        {
            Modifiers =
            {
                typeInfo =>
                {
                    if (typeInfo.Type == typeof(StepBaseDto))
                    {
                        // 添加所有需要支持的派生类
                        typeInfo.PolymorphismOptions.AddDerivedType(typeof(StartDateStepDto));
                    }
                }
            }
        };
    });

2. 适配ABP框架的序列化配置

ABP框架5.x有自己的序列化配置体系,需在模块类中配置AbpSystemTextJsonSerializerOptions:

public override void ConfigureServices(ServiceConfigurationContext context)
{
    Configure<AbpSystemTextJsonSerializerOptions>(options =>
    {
        options.JsonSerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver
        {
            Modifiers =
            {
                typeInfo =>
                {
                    if (typeInfo.Type == typeof(StepBaseDto))
                    {
                        typeInfo.PolymorphismOptions.AddDerivedType(typeof(StartDateStepDto));
                    }
                }
            }
        };
    });
}

3. 确保Automapper映射保留派生类类型

如果映射过程中Automapper将派生类实例转换为基类,会导致序列化丢失属性,需在Automapper配置中添加Include规则:

// 配置实体到Dto的映射
CreateMap<StartDateStep, StartDateStepDto>();
CreateMap<StepBase, StepBaseDto>()
    .Include<StartDateStep, StartDateStepDto>(); // 关联派生类映射

// 如有其他派生类,重复上述Include配置

这样当映射StepBase集合时,Automapper会根据实际实体类型创建对应的Dto派生类实例,序列化时自然保留子类属性。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 22:50:28