2016-08-29 8 views
2

Dictionary<string, AbstractDataObject>を逆シリアル化したいと思います。 AbstractDataObjectは抽象クラスであり、SomeClass1SomeClass2から継承しています。辞書(文字列)のキー値は、クラスの名前です:JSON推論クラスのタイプは辞書キーに基づいています

{ 
    "StoredData": { 
    "SomeClass1": { 
     "Foo": "Test" 
    }, 
    "SomeClass2": { 
     "Bar": 123 
    } 
    } 
} 

クラスは(簡体字)、次のようになります。

public class Data 
{ 
    public Dictionary<string, AbstractDataObject> StoredData { get; set; } 
} 

public abstract class AbstractDataObject 
{ 
} 

public class SomeClass1 : AbstractDataObject 
{ 
    public string Foo { get; set; } 
} 

public class SomeClass2 : AbstractDataObject 
{ 
    public int Bar { get; set; } 
} 

どのように私は推測するJson.NETを伝えることができますDictionaryキーに基づくクラス型ですか?私は周りを見回してきましたが、私は、この機能

+1

タイプ名の使用は、完全に分離されたクライアント/サーバを可能にするための、シリアライゼーションの典型的な目的に反するため、危険です。明示的な契約があるように設計する方法はありますか? –

+0

@SilasReinagel明示的な契約はどういう意味ですか? – jacobz

+0

たとえば、特定のリモート呼び出しのために、クライアントコードに具体的なデータオブジェクトを使用します。 –

答えて

1

の実装を開始する場所あなたがこれを処理するためにカスタムJsonConverterを作ることができるか不明だ:

public class CustomDictionaryConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(Dictionary<string, AbstractDataObject>); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     var dict = new Dictionary<string, AbstractDataObject>(); 
     JObject jo = JObject.Load(reader); 
     foreach (JProperty prop in jo.Properties()) 
     { 
      switch (prop.Name) 
      { 
       case "SomeClass1": 
        dict.Add("SomeClass1", prop.Value.ToObject<SomeClass1>(serializer)); 
        break; 

       case "SomeClass2": 
        dict.Add("SomeClass2", prop.Value.ToObject<SomeClass2>(serializer)); 
        break; 
      } 
     } 
     return dict; 
    } 

    public override bool CanWrite 
    { 
     get { return false; } 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

次に、このようにそれを使用します。

Data data = JsonConvert.DeserializeObject<Data>(json, new CustomDictionaryConverter()); 

Fiddle:https://dotnetfiddle.net/ba4wB6

関連する問題