ASP.NET API接收JSON时派生类属性未映射的解决方法
ASP.NET API 派生类属性映射修复方案
方案一:System.Text.Json 多态配置(默认序列化器)
ASP.NET Core 3.0+ 默认使用 System.Text.Json,要支持派生类映射,需通过特性或配置启用多态识别:
步骤1:给基类添加多态特性
直接在基类上标记多态规则,指定类型鉴别器和对应派生类:
// 基类 [JsonPolymorphic(TypeDiscriminatorPropertyName = "$type")] // 映射派生类,typeDiscriminator 为JSON中要传入的类型标识 [JsonDerivedType(typeof(SkillBonusDetail), typeDiscriminator: "SkillBonus")] [JsonDerivedType(typeof(PerformanceBonusDetail), typeDiscriminator: "PerformanceBonus")] public class EmployeeBonusDetail { public int EmployeeId { get; set; } public decimal BaseAmount { get; set; } } // 派生类 public class SkillBonusDetail : EmployeeBonusDetail { public string SkillCode { get; set; } public decimal SkillMultiplier { get; set; } }
步骤2:请求JSON中携带类型标识
提交的JSON必须包含指定的$type字段,序列化器会自动匹配到对应派生类:
{ "$type": "SkillBonus", "EmployeeId": 1001, "BaseAmount": 600.00, "SkillCode": "ASP.NET", "SkillMultiplier": 1.8 }
方案二:使用 Newtonsoft.Json(Json.NET)
如果项目依赖 Newtonsoft.Json,可通过配置类型处理解决:
步骤1:安装并注册NewtonsoftJson
// 安装 NuGet 包:Microsoft.AspNetCore.Mvc.NewtonsoftJson builder.Services.AddControllers() .AddNewtonsoftJson(options => { // 启用类型名称处理,自动识别派生类 options.SerializerSettings.TypeNameHandling = TypeNameHandling.Objects; // 可选:关闭类型名称的完全限定,简化JSON中的类型标识 // options.SerializerSettings.TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple; });
步骤2:构造包含类型信息的JSON
JSON中需携带$type字段,指定派生类的类型(可简化为类名+命名空间):
{ "$type": "YourProject.Models.SkillBonusDetail, YourProject", "EmployeeId": 1001, "BaseAmount": 600.00, "SkillCode": "ASP.NET", "SkillMultiplier": 1.8 }
注意:
TypeNameHandling存在反序列化安全风险,建议仅在可信请求场景使用,或自定义类型映射限制允许的类型。
方案三:手动解析(无多态序列化依赖)
如果不想修改全局序列化配置,可手动解析JSON并转换为对应派生类:
接口参数改用JObject接收
[HttpPost("SaveGeneratedSkillBonusDetails")] public IActionResult SaveBonusDetails([FromBody] JObject bonusJson) { // 从JSON中读取自定义类型标识(如BonusType) var bonusType = bonusJson["BonusType"]?.ToString(); EmployeeBonusDetail bonusDetail = bonusType switch { "Skill" => bonusJson.ToObject<SkillBonusDetail>(), "Performance" => bonusJson.ToObject<PerformanceBonusDetail>(), _ => null }; if (bonusDetail == null) return BadRequest("无效的奖金类型"); // 执行保存逻辑 return Ok(); }
对应的请求JSON需包含BonusType字段:
{ "BonusType": "Skill", "EmployeeId": 1001, "BaseAmount": 600.00, "SkillCode": "ASP.NET", "SkillMultiplier": 1.8 }
额外注意事项
- 确保JSON字段名与模型属性名匹配(System.Text.Json默认支持大小写不敏感,但建议保持一致,或用
[JsonPropertyName]特性指定映射关系) - 如果使用System.Text.Json,若模型属性为PascalCase而JSON用camelCase,可配置
options.JsonSerializerOptions.PropertyNamingPolicy = null;关闭驼峰转换,或用特性指定字段名。
内容的提问来源于stack exchange,提问作者Alvaro
相关产品推荐
相关产品推荐

