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

.NET POST API接收两种不同类型对象的问题排查

问题原因

默认的JSON反序列化器(比如System.Text.Json)处理List<FieldStructure>时,只会把所有JSON对象实例化为基类FieldStructure,不会自动识别子类FieldStructureRelation,导致子类特有的AppRelationId和AppRelationName属性丢失。解决这个问题需要配置多态反序列化规则,告诉序列化器如何根据JSON字段判断实例化对应的子类。


解决方案一:使用System.Text.Json(.NET Core 3.0+ 默认)

通过给基类添加[JsonDerivedType]特性,指定子类及其匹配条件(这里用Type字段值区分):

修改基类FieldStructure

using System.Text.Json.Serialization;

[JsonDerivedType(typeof(FieldStructure), typeDiscriminator: "text")]
[JsonDerivedType(typeof(FieldStructure), typeDiscriminator: "boolean")]
[JsonDerivedType(typeof(FieldStructure), typeDiscriminator: "decimal")]
[JsonDerivedType(typeof(FieldStructureRelation), typeDiscriminator: "itemRelation")]
public class FieldStructure
{
    public FieldStructure(string name, string type)
    {
        Name = name;
        Type = type;
        NameAsProperty = name.ToLower().Replace(" ", "_");
    }

    public FieldStructure() { }

    public string Name { get; set; } = string.Empty;
    public string NameAsProperty { get; set; } = string.Empty;
    [JsonDiscriminator] // 指定该字段作为类型判别依据
    public string Type { get; set; } = string.Empty;
}

public class FieldStructureRelation : FieldStructure
{
    public FieldStructureRelation(FieldStructure fieldStructure, string appRelationId, string appRelationName) 
        : base(fieldStructure.Name, fieldStructure.Type)
    {
        this.AppRelationName = appRelationName;
        this.AppRelationId = appRelationId;
    }

    public FieldStructureRelation() { }

    public string AppRelationId { get; set; } = string.Empty;
    public string AppRelationName { get; set; } = string.Empty;
}

说明:

  • [JsonDiscriminator]标记Type字段作为类型判断的依据
  • [JsonDerivedType]分别指定不同Type值对应的类:普通类型(text/boolean/decimal)对应基类,itemRelation对应子类FieldStructureRelation

解决方案二:使用Newtonsoft.Json(Json.NET)

如果项目使用Newtonsoft.Json,可通过自定义类型转换器实现:

步骤1:安装Newtonsoft.Json包

Install-Package Newtonsoft.Json

步骤2:添加自定义类型转换器

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class FieldStructureConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(FieldStructure);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        // 根据Type字段判断实例化的类
        string type = jo["Type"]?.Value<string>();
        if (type == "itemRelation")
        {
            return jo.ToObject<FieldStructureRelation>(serializer);
        }
        else
        {
            return jo.ToObject<FieldStructure>(serializer);
        }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }
}

步骤3:给基类添加转换器特性

[JsonConverter(typeof(FieldStructureConverter))]
public class FieldStructure
{
    // 原类代码保持不变
}

步骤4:配置ASP.NET Core使用Newtonsoft.Json

在Program.cs中替换默认序列化器:

builder.Services.AddControllers()
    .AddNewtonsoftJson();

验证测试

发送你提供的示例JSON请求后,控制器CreateApp方法中的request.Fields列表里,第四个对象会被正确实例化为FieldStructureRelation,AppRelationId和AppRelationName属性会保留对应值。

内容的提问来源于stack exchange,提问作者Nono-Man

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 21:12:45