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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 00:30:10