在反序列化的JSON.NET对象中存储原始JSON字符串
实现Newtonsoft反序列化时保留原始JSON字符串到Message对象
看起来你已经选对了方案——自定义JsonConverter确实是实现这个需求的最优解。咱们把这个转换器补全,让它既能正确解析Type属性,又能把原始JSON字符串完整存到Original字段里。
完整的自定义JsonConverter实现
首先,咱们把MessageConverter写完整,它需要实现ReadJson(处理反序列化,这是你需求的核心)和WriteJson(处理序列化,可选但建议补全)两个方法:
public class MessageConverter : JsonConverter<Message> { // 反序列化核心逻辑:从JSON字符串转Message对象时保存原始JSON public override Message ReadJson(JsonReader reader, Type objectType, Message existingValue, bool hasExistingValue, JsonSerializer serializer) { // 先把整个JSON读取成JToken,这样能拿到完整的原始JSON字符串 JToken token = JToken.Load(reader); // 将JToken转为原始JSON字符串(用Formatting.None确保输出紧凑格式,和输入一致) string originalJson = token.ToString(Formatting.None); // 创建Message对象,传入原始JSON Message message = new Message(originalJson); // 从JToken里解析Type属性赋值给对象 message.Type = token["Type"]?.ToString(); return message; } // 序列化逻辑:如果需要把Message转回JSON,这里可以自定义输出格式 public override void WriteJson(JsonWriter writer, Message value, JsonSerializer serializer) { // 方案1:直接序列化Type和Original两个属性 JObject obj = new JObject(); obj["Type"] = value.Type; obj["Original"] = value.Original; obj.WriteTo(writer); // 方案2:如果希望序列化时输出原始的Original JSON(而不是把它作为字符串),可以用下面的代码: // JToken originalToken = JToken.Parse(value.Original); // originalToken.WriteTo(writer); } }
关键细节说明
- ReadJson方法:通过
JToken.Load(reader)读取整个JSON节点,再用ToString(Formatting.None)获取原始JSON字符串,确保和输入的格式一致(不会额外增加缩进)。然后调用你的构造函数初始化Message,再从JToken里提取Type属性赋值。 - WriteJson方法:提供了两种方案,你可以根据需求选择:
- 方案1:把
Message的Type和Original作为两个独立字段输出JSON。 - 方案2:直接输出
Original里的原始JSON,相当于还原最初的输入(适合需要反向还原的场景)。
- 方案1:把
使用示例
现在你可以正常反序列化JSON字符串到Message对象,原始JSON会自动存在Original属性里:
// 示例JSON string inputJson = "{\"Type\":\"Alert\",\"Content\":\"System update available\"}"; // 反序列化 Message msg = JsonConvert.DeserializeObject<Message>(inputJson); // 验证结果 Console.WriteLine(msg.Type); // 输出:Alert Console.WriteLine(msg.Original); // 输出:{"Type":"Alert","Content":"System update available"}
额外注意点
如果你的原始JSON输入带有缩进或者特殊格式,而你需要完全精确保留输入的每一个字符(包括空格、换行),可以修改ReadJson方法,直接读取JsonReader的原始值:
// 替代JToken.Load的方式,直接读取原始字符串 string originalJson = reader.Value.ToString();
不过这种方式只适合JSON是单个字符串的场景,大多数情况下用JToken的方式更可靠,因为它能处理复杂的JSON结构。
内容的提问来源于stack exchange,提问作者Maxim Gershkovich
相关产品推荐
相关产品推荐

