.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
相关产品推荐
相关产品推荐

