2016-08-15 16 views
0

の名前を取得するために働くことはありません。CustomConverterは、私はこのようなJSONを受け取るオブジェクト

public class JsonObjectsToListConverter : JsonConverter 
{ 

    public JsonObjectsToListConverter() 
    { 

    } 

    public override bool CanConvert(Type objectType) 
    { 
     return (objectType == typeof(HashSet<String>)); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     JToken jtoken = JToken.Load(reader); 
     JObject jObjectCast = jtoken.Value<JObject>(); 

     List<String> listPers = (from prop in jObjectCast.Properties() 
           select prop.Name).ToList(); 
     return listPers; 
    } 

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

と一覧部材とPersonクラス: は、だから私はCustomJsonConverter持っ

public class Persons 
    { 
     [JsonConverter(typeof(JsonObjectsToListConverter))] 
     public List<String> listPers { get; set; } 
    } 

問題は、私のようなJSONに親オブジェクトを追加する場合を除き、CustomConverterリターンヌル:

人物クラスの
{"listP": 
    { 
    "Bryan":{ 
.... 

[JsonProperty("listP")]です。

デシリアライズ時に何が起こるのか理解できず、なぜPropertyName属性なしで正しく動作しないのですか。

答えて

1

以下の説明は非常に単純化されていますが、実際のデシリアライズ処理にかなり近いものです。

JsonConvert.DeserializeObjectメソッドに文字列とターゲット型を指定すると、指定した型の構造体を文字列の構造体と比較し始めます。提供された型のパブリックプロパティを検索し、文字列内で同じプロパティのオカレンスを検索します。 json配列とjson配列の名前を使用して型をリンクするまで、文字列で指定するjson配列が "listP"という名前のプロパティに入ることはわかりません。

さて、あなたは必要ないがJsonProperty属性で「listP」プロパティ名を指定する必要があります。 json配列にはクラスプロパティと同じ名前があれば十分です:"listPers"

public class Persons 
{ 
    public List<String> ListPers { get; set; } 
} 

public class JsonObjectsToPersonsConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return (objectType == typeof(Persons)); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     Persons value = new Persons(); 
     JToken jtoken = JToken.Load(reader); 
     JObject jObjectCast = jtoken.Value<JObject>(); 

     List<String> listPers = (from prop in jObjectCast.Properties() 
           select prop.Name).ToList(); 
     return new Persons { ListPers = listPers}; 
    } 

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

:あなたはJSON自体、不要なプロパティの装飾に追加のオーバーヘッドなしに、しかし、直列化復元のプロセスを簡素化したい場合は

、以下のようなコードを書くことが容易になるだろう

var persons = JsonConvert.DeserializeObject<Persons>(
    @"{ 
     'Bryan': { 
      'age': 25, 
      'city': 'Miami' 
     }, 
     'Jeff': { 
      'age': 24, 
      'city': 'Tokyo' 
     } 
    }", 
    new JsonObjectsToPersonsConverter()); 
+0

しかし、コンバータを使用して、例の 'Animals'クラスのメンバーリストで同じ構造の別のJSONを逆シリアル化するとします。どのようにできるのか ?最後に、一般的な「コンバータ」を使用する。 – Neyoh

+0

これはトレードオフです。同様に構造化されたデータの配列を名前のリストに変換するための一般的なものを書くか、または特定のクラスごとに変換したものを作成します。最初のケースでは、jsonで配列名を指定する必要があります。 2番目の方法では、コンバーターの継承階層を作成し、実際のロジックを基本クラスに移動させることができます。しかし、あなたが "ブライアン"と "ジェフ"のリストを動物のリストに変換する必要があるときは私は見ません... – galenus

関連する問題