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默认支持派生类型的序列化,可通过以下步骤切换:
- 安装NuGet包:
Microsoft.AspNetCore.Mvc.NewtonsoftJson - 在
Program.cs中配置:
builder.Services.AddControllers() .AddNewtonsoftJson();
内容的提问来源于stack exchange,提问作者Mehmet Karagöz
相关产品推荐
相关产品推荐

