ASP.NET Core 7多态响应未返回序列化鉴别器的解决咨询
问题
ASP.NET Core 7接口在反序列化多态请求体时能正确识别类型鉴别器,但序列化多态响应时却不包含该鉴别器。有意思的是,手动使用System.Text.Json.JsonSerializer进行序列化时,鉴别器会被正确输出。请问需要进行哪些配置,才能让ASP.NET Core在响应中包含鉴别器?
using Microsoft.AspNetCore.Mvc; using System.Diagnostics; using System.Text.Json; using System.Text.Json.Serialization; [JsonDerivedType(typeof(Foo), "Foo")] [JsonDerivedType(typeof(Bar), "Bar")] public abstract class Base { } public class Foo : Base { public string? Name { get; set; } } public class Bar : Base { public string? Name { get; set; } } public class Controller : ControllerBase { [HttpPost("")] public Base Action(Base request) { return request; } }
如下包含鉴别器的请求可被正确反序列化:
{ "$type": "Bar" }
但接口返回的响应未包含预期的鉴别器:
{ "name": null }
解决方案
问题根源在于ASP.NET Core默认的System.Text.Json序列化配置未启用多态类型信息写入。反序列化时默认支持读取鉴别器,但响应序列化需要显式开启相关配置。
你需要在Program.cs中修改Controllers的Json序列化选项,确保启用多态类型信息的输出:
方式一:基于特性配置(推荐,与代码中[JsonDerivedType]保持一致)
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers() .AddJsonOptions(options => { // 使用DefaultJsonTypeInfoResolver以识别基类上的JsonDerivedType特性 options.JsonSerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver(); // 可选:保持属性命名为驼峰式,与默认行为一致 options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; }); var app = builder.Build(); app.MapControllers(); app.Run();
方式二:手动配置多态规则
如果需要更精细的控制,可以直接在配置中指定多态选项:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.TypeInfoResolverChain.Insert(0, new DefaultJsonTypeInfoResolver { Modifiers = { typeInfo => { if (typeInfo.Type == typeof(Base)) { typeInfo.PolymorphismOptions = new JsonPolymorphismOptions { TypeDiscriminatorPropertyName = "$type", // 指定鉴别器字段名 IgnoreUnrecognizedTypeDiscriminators = true, DerivedTypes = { new JsonDerivedType(typeof(Foo), "Foo"), new JsonDerivedType(typeof(Bar), "Bar") } }; } } } }); }); var app = builder.Build(); app.MapControllers(); app.Run();
修改完成后,接口响应会包含预期的类型鉴别器:
{ "$type": "Bar", "name": null }
注:手动调用
JsonSerializer.Serialize时能正常输出鉴别器,是因为默认的DefaultJsonTypeInfoResolver会自动识别基类上的[JsonDerivedType]特性,但ASP.NET Core默认配置中使用的类型解析器未包含该逻辑,因此需要显式指定。
内容的提问来源于stack exchange,提问作者Selig Drahcir
相关产品推荐
相关产品推荐

