反序列化时如何根据另一个属性的JsonProperty值忽略指定属性
反序列化时如何根据另一个属性的JsonProperty值忽略指定属性
这个场景我太熟悉了——默认的Json.NET(Newtonsoft.Json)序列化规则没法根据其他属性的动态值来调整反序列化逻辑,你遇到的类型不匹配错误,就是因为StatusCode=400时response是字符串,而其他时候是JSON对象,直接用默认规则肯定会炸。
解决的核心思路是给APIMatrix类写一个自定义Json转换器,让它在反序列化时先判断statusCode的值,再决定怎么处理response属性。下面是具体的实现步骤:
1. 实现自定义JsonConverter
创建一个继承自JsonConverter<APIMatrix>的转换器,在ReadJson方法里做逻辑判断:
public class APIMatrixConverter : JsonConverter<APIMatrix> { public override APIMatrix ReadJson(JsonReader reader, Type objectType, APIMatrix existingValue, bool hasExistingValue, JsonSerializer serializer) { // 先把JSON加载成JObject,方便读取单个属性 var jObject = JObject.Load(reader); var matrix = new APIMatrix(); // 先反序列化StatusCode属性 serializer.Populate(jObject.CreateReader(), matrix); // 判断StatusCode是否为400 if (matrix.StatusCode == 400) { // 直接把Response设为null,跳过反序列化 matrix.Response = null; } else { // 正常反序列化Response为APIResponse对象 matrix.Response = jObject["response"].ToObject<APIResponse>(serializer); } return matrix; } // 如果你不需要自定义序列化逻辑,WriteJson可以留空或者抛出NotImplementedException public override void WriteJson(JsonWriter writer, APIMatrix value, JsonSerializer serializer) { serializer.Serialize(writer, value); } }
2. 在反序列化时使用这个转换器
修改你的JsonSerializerSettings,把自定义转换器加进去,再执行反序列化:
var jsonSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, MissingMemberHandling = MissingMemberHandling.Ignore, // 添加自定义转换器 Converters = new List<JsonConverter> { new APIMatrixConverter() } }; var apiRoot = JsonConvert.DeserializeObject<APIRoot>(response.Content!, jsonSettings)!;
为什么之前的设置没用?
你之前用的NullValueHandling和MissingMemberHandling只能处理属性缺失或者值为null的情况,但这里的问题是response属性存在,但类型不匹配(字符串 vs APIResponse对象),所以这两个设置根本管不到这种场景,必须用自定义转换器来干预反序列化过程。
额外提示
如果你的APIResponse类本身也有复杂的反序列化逻辑,不用担心,上面的代码里用了serializer.ToObject<APIResponse>,会自动应用你原来的序列化设置和其他转换器,不会冲突。
内容来源于stack exchange
相关产品推荐
相关产品推荐

