如何通过一次反序列化将含转义字符的嵌套JSON转为嵌套POCO?
一次反序列化嵌套转义JSON为POCO的解决方案
问题场景
我们收到的JSON消息中包含带转义字符的嵌套JSON对象,示例原始字符串如下:
string rawMessage = "{\"lte\": \"{\\\"lst\\\":5,\\\"lrs\\\":19,\\\"lrq\\\":3}\"}";
这种原始字符串测试难度高且易出错,我们希望直接操作POCO而非原始字符串。
初始模型定义如下:
public class Message{ public string lte { get; set;} }
执行JsonConvert.DeserializeObject<Message>(rawMessage)可正常反序列化,调试时lte属性显示嵌套JSON内容。
我们期望直接反序列化为嵌套POCO模型:
public class Message{ public Lte lte { get; set;} } public class Lte{ public int lst { get; set;} public int lrs { get; set;} public int lrq { get; set;} }
但直接执行JsonConvert.DeserializeObject<Message>(rawMessage)会抛出类型转换异常。目前仅能通过两次反序列化实现转换:
var message = JsonConvert.DeserializeObject<Message>(rawMessage); var embeddedMessage = JsonConvert.DeserializeObject<Lte>(message.lte);
解决方案:用自定义JsonConverter特性实现一次反序列化
可以通过给Message类的lte属性添加自定义JsonConverter特性,实现一次反序列化完成转换。
步骤1:实现自定义JsonConverter
创建继承自JsonConverter的转换器,负责将字符串形式的嵌套JSON反序列化为目标POCO:
public class EmbeddedJsonConverter<T> : JsonConverter<T> { public override T ReadJson(JsonReader reader, Type objectType, T existingValue, bool hasExistingValue, JsonSerializer serializer) { var jsonString = reader.Value as string; if (string.IsNullOrEmpty(jsonString)) return default; return JsonConvert.DeserializeObject<T>(jsonString); } public override void WriteJson(JsonWriter writer, T value, JsonSerializer serializer) { var jsonString = JsonConvert.SerializeObject(value); writer.WriteValue(jsonString); } }
步骤2:给POCO属性添加特性装饰
修改Message类,给lte属性添加JsonConverter特性,指定使用自定义转换器:
public class Message{ [JsonConverter(typeof(EmbeddedJsonConverter<Lte>))] public Lte lte { get; set;} } public class Lte{ public int lst { get; set;} public int lrs { get; set;} public int lrq { get; set;} }
步骤3:执行一次反序列化
现在直接执行以下代码即可完成一次反序列化,无需手动处理嵌套JSON:
var message = JsonConvert.DeserializeObject<Message>(rawMessage); // 此时message.lte已直接是Lte类型实例,可直接访问lst、lrs、lrq属性
补充说明
如果仅需反序列化(不需要序列化回原始格式),可简化WriteJson方法,直接抛出NotImplementedException即可。
内容的提问来源于stack exchange,提问作者Ross Halliday
相关产品推荐
相关产品推荐

