3

ドキュメント データベースでストレージ形式として使用され、サービス バス経由で送信される JSON ドキュメントが既に定義されています。

これらは、JSON.NET を使用して具体的なクラスに逆シリアル化されます。追加のデータを保持するために既存のプロパティを変更したいと考えています (たとえば、現在クラスの 1 つに文字列の配列が含まれていますが、文字列とタイムスタンプを含むクラスの配列にしたいと考えています。)

ただし、古いドキュメント形式を逆シリアル化できる必要があります。おそらくカスタム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.

4

1 に答える 1

0

現在の例では、エントリ クラスに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; }
}
于 2013-04-12T17:35:31.820 に答える