使用JSON.NET升级JSON文档

本文关键字:JSON 文档 升级 NET 使用 | 更新日期: 2023-09-27 18:08:44

我们已经定义了一些JSON docúments,它们被用作文档数据库中的存储格式,并通过服务总线发送。

使用JSON.NET将这些反序列化成具体的类。我现在想修改一个现有的属性来保存额外的数据(例如,目前我的一个类包含字符串数组,但现在我希望它是一个类的数组,包含一个字符串加一个时间戳)

但是,我仍然需要能够反序列化旧的文档格式。有没有一种方法,也许是使用自定义的JsonConverter,在旧的文档格式出现时无缝地转换为新的文档格式?在序列化方面,我希望所有文档都以新格式保存。

既然我被要求添加技术细节,这里有一个人为的例子供讨论:

public class Document
{
    public string[] Array { get; set; }
}

升级为:

public class Document
{
    public class Entry
    {
        public string Value { get; set; }
        public DateTime Timestamp { get; set; }
    }
    public Entry[] Array { get; set; }
}

在这个例子中,让我们假设任何旧格式的文档都应该以DateTime.UtcNow的时间戳结束。

使用JSON.NET升级JSON文档

在当前的示例中,您可以为条目类使用CustomCreationConverter。CustomCreationConverter<Entry>的实现:

public class DocumentEntryCreationConverter : CustomCreationConverter<Document.Entry>
{
    public override Document.Entry Create(Type objectType)
    {
        return new Document.Entry();
    }
    public override object ReadJson(
        JsonReader reader, 
        Type objectType,
        object existingValue, 
        JsonSerializer serializer)
    {
        // If this is not an object - looks like an old format
        // So we need only set a value
        if (reader.TokenType == JsonToken.String) 
        {
            Document.Entry entry = this.Create(objectType);
            entry.Value = reader.Value as string;
            return entry;
        }
        else
        {
            // This is new format, we can recognise it as an object
            Debug.Assert(
                reader.TokenType == JsonToken.StartObject, 
                "reader.TokenType == JsonToken.StartObject");
            return base.ReadJson(reader, objectType, existingValue, serializer);
        }
    }
}

这是你如何将它应用于条目类:

public class Document
{
    [JsonConverter(typeof(DocumentEntryCreationConverter))]
    public class Entry
    {
        public string Value { get; set; }
        public DateTime Timestamp { get; set; }
    }
    public Entry[] Array { get; set; }
}