如何在JSON反序列化时忽略字符串类型的Order属性?
根据JSON字段类型动态忽略属性的解决方案
直接使用[JsonIgnore]或其相关静态配置无法满足你的需求——因为这些配置是固定的,没法根据JSON中order字段的实际类型动态决定是否绑定。下面提供两种可行的实现方式:
方法一:自定义JSON转换器(推荐)
编写一个针对Data类的自定义转换器,在反序列化过程中判断order字段的类型,决定是否绑定到Order属性:
1. 实现自定义转换器
using System.Text.Json; using System.Text.Json.Serialization; public class DataConverter : JsonConverter<Data> { public override Data Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { using JsonDocument doc = JsonDocument.ParseValue(ref reader); var root = doc.RootElement; var data = new Data(); // 解析id字段(映射到OrderId) if (root.TryGetProperty("id", out JsonElement idElem)) { data.OrderId = idElem.GetString(); } // 处理order字段 if (root.TryGetProperty("order", out JsonElement orderElem)) { // 仅当order是对象类型时,反序列化为Order实例 if (orderElem.ValueKind == JsonValueKind.Object) { data.Order = JsonSerializer.Deserialize<Order>(orderElem.GetRawText(), options); } // 字符串类型则直接忽略,不赋值 } return data; } public override void Write(Utf8JsonWriter writer, Data value, JsonSerializerOptions options) { // 如果不需要序列化Data类,可抛出NotImplementedException;否则实现序列化逻辑 JsonSerializer.Serialize(writer, value, options); } }
2. 注册转换器
有两种方式注册:
- 全局注册(适用于所有使用该模型的接口):在
Program.cs中配置控制器的JSON选项
builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new DataConverter()); });
- 局部注册(仅当前模型生效):直接在
Data类上标记转换器特性
[JsonConverter(typeof(DataConverter))] public class Data { [JsonPropertyName("id")] public string OrderId { get; set; } public Order Order { get; set; } }
方法二:利用扩展数据与反序列化回调
通过[JsonExtensionData]接收未匹配的字段,再借助反序列化回调处理order字段:
修改Data类:
using System.Text.Json; using System.Text.Json.Serialization; public class Data { [JsonPropertyName("id")] public string OrderId { get; set; } public Order Order { get; set; } // 接收所有未匹配的JSON字段 [JsonExtensionData] private Dictionary<string, JsonElement> _extraData; // 反序列化完成后触发的回调 [OnDeserialized] private void ProcessExtraData(StreamingContext context) { if (_extraData.TryGetValue("order", out JsonElement orderElem)) { if (orderElem.ValueKind == JsonValueKind.Object) { Order = JsonSerializer.Deserialize<Order>(orderElem.GetRawText()); } // 字符串类型忽略 } } }
这种方法无需额外注册转换器,仅修改模型类即可实现需求,适合轻量场景。
内容的提问来源于stack exchange,提问作者Viktor Bylbas
相关产品推荐
相关产品推荐

