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

ASP.NET Core API中AutoMapper继承映射序列化异常问题

问题描述

开发ASP.NET Core API项目时,使用AutoMapper实现领域实体(继承结构)到视图模型的映射,已配置AutoMapper的Include继承映射规则。采用自定义Response<T>类处理API响应,但发现派生视图模型(如GetAllMultipleChoiceQuestionViewModel)序列化后仅包含基类视图模型(BaseGetAllQuestionViewModel)的属性。调试时确认控制器返回前的响应数据包含派生类属性,但序列化后丢失。

简化代码如下:

模型

  • Question(基类)
  • MultipleChoiceQuestion(继承自Question)
  • Choice

视图模型

  • BaseGetAllQuestionViewModel
  • GetAllMultipleChoiceQuestionViewModel

AutoMapper配置

CreateMap<Question, BaseGetAllQuestionViewModel>()
    .Include<MultipleChoiceQuestion, GetAllMultipleChoiceQuestionViewModel>();

CreateMap<MultipleChoiceQuestion, GetAllMultipleChoiceQuestionViewModel>()
    .ForMember(dest => dest.Choices, opt => opt.MapFrom(src => src.Choices));

查询处理器

public async Task<Response<IEnumerable<BaseGetAllQuestionViewModel>>> Handle(GetAllQuestionsBySurveyContentIdQuery request, CancellationToken cancellationToken)
{
    var questions = await _questionRepositoryAsync.GetAllQuestionsBySurveyContentIdAsync(request.SurveyContentId);
    var questionViewModels = questions.ToList(); // 确保为具体列表

    var response = new Response<IEnumerable<BaseGetAllQuestionViewModel>>(questionViewModels);
    return response;
}

控制器

[HttpGet("GetAllQuestionsBySurveyContentId")]
// [Authorize(Roles = "SuperAdmin")]
public async Task<IActionResult> GetAllQuestionsBySurveyContentId([FromQuery] GetAllQuestionsBySurveyContentIdQuery query)
{
    var response = await Mediator.Send(query);
    return Ok(response);
}
解决方案

问题根源是默认的JSON序列化器(System.Text.Json)基于编译时类型(BaseGetAllQuestionViewModel)进行序列化,无法自动识别运行时的派生类型,导致仅序列化基类属性。以下是三种解决方式:

方式一:给基类视图模型添加[JsonDerivedType]特性(.NET 6+推荐)

直接在基类上标记所有派生类型,告知序列化器识别这些派生类:

using System.Text.Json.Serialization;

[JsonDerivedType(typeof(GetAllMultipleChoiceQuestionViewModel))]
public class BaseGetAllQuestionViewModel
{
    // 基类属性定义
}

public class GetAllMultipleChoiceQuestionViewModel : BaseGetAllQuestionViewModel
{
    public IEnumerable<Choice> Choices { get; set; }
}

方式二:全局配置Json序列化选项

在Program.cs(或Startup.cs)中配置序列化器,添加派生类型映射,无需修改视图模型:

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

方式三:切换为Newtonsoft.Json序列化

Newtonsoft.Json默认支持派生类型的序列化,可通过以下步骤切换:

  1. 安装NuGet包:Microsoft.AspNetCore.Mvc.NewtonsoftJson
  2. 在Program.cs中配置:
builder.Services.AddControllers()
    .AddNewtonsoftJson();

内容的提问来源于stack exchange,提问作者Mehmet Karagöz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 11:48:20