2011-07-19 4 views
2

Je suis nouveau à l'aide de JSON et j'ai du mal à retourner spécifiquement une liste, dans une liste. Je reçois le JSON suivant:Json retournant une liste dans une liste

{ 
    "parameters": { 
     "tbdb": "trudon", 
     "min_prefix_length": "2", 
     "service": "prefix", 
     "template": "service.json", 
     "term_prefix": "plu"}, 
    "termHints": [ 
     { 
      "name": "Plumbers & Sanitary Engineers", 
      "id":"209654", 
      "values": { 
       "value":"Plumbers & Sanitary Engineers", 
       "pre_em":"", 
       "em":"Plu", 
       "post_em":"mbers & Sanitary Engineers", 
       "nature":"PT", 
       "id":"209654" 
      } 
     }, 
    ], 
    "facets": [ 
     { 
      "id":"209654", 
      "name":"Plumbers & Sanitary Engineers" 
     } 
    ], 
    "total":1 
} 

Je desrialized cela en utilisant le JSON DataContractJsonSerializer et il se présente comme suit:

modifié: apporté les modifications qui ont été proposées par carlosfigueira ici

[DataContract] 
    public class AutoCompleteResponse 
    { 
     [DataMember(Name = "parameters")] 
     public Parameter Parameters { get; set; } 
     [DataMember(Name = "termHints")] 
     public List<termHints> hints { get; set; } 
     [DataMember(Name = "total")] 
     public string Total { get; set; } 
    } 
    [DataContract] 
    public class Parameter 
    { 
     [DataMember(Name = "tbdb")] 
     public string tbdb { get; set; } 
     [DataMember(Name = "min_prefix_length")] 
     public string min_prefix_length { get; set; } 
     [DataMember(Name = "service")] 
     public string service { get; set; } 
     [DataMember(Name = "template")] 
     public string template { get; set; } 
     [DataMember(Name = "term_prefix")] 
     public string term_prefrix { get; set; } 
    } 
    [DataContract] 
    public class termHints 
    { 
     [DataMember(Name = "name")] 
     public string Name { get; set; } 
     [DataMember(Name = "id")] 
     public string id { get; set; } 
     [DataMember(Name = "values")] 
     public values Values { get; set; } 
     [DataMember(Name = "facets")] 
     public facets Facets { get; set; } 

    } 
    [DataContract] 
    public class values 
    { 
     [DataMember(Name = "value")] 
     public string value_name { get; set; } 
     [DataMember(Name = "pre_em")] 
     public string pre_em { get; set; } 
     [DataMember(Name = "em")] 
     public string em { get; set; } 
     [DataMember(Name = "post_em")] 
     public string post_em { get; set; } 
     [DataMember(Name = "nature")] 
     public string nature { get; set; } 
     [DataMember(Name = "id")] 
     public string value_id { get; set; } 
    } 
    [DataContract] 
    public class facets 
    { 
     [DataMember(Name = "id")] 
     public string facet_id { get; set; } 
     [DataMember (Name = "name")] 
     public string facet_name {get; set; } 
    } 

la sérialisation je ressemble à ce qui suit:

WebClient w = new WebClient(); 
    w.DownloadStringCompleted += (a, b) => 
    { 
     // Check for errors 
     if (b == null) { return; } 
     if (b.Error != null) { return; } 
     if (string.IsNullOrEmpty(b.Result)) { return; } 

     // Desearealize from JSON to .NET objects 
     Byte[] bytes = Encoding.Unicode.GetBytes(b.Result); 
     MemoryStream memoryStream = new MemoryStream(bytes); 
     DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(AutoCompleteResponse)); 
     AutoCompleteResponse autocompleteSearchResponse = dataContractJsonSerializer.ReadObject(memoryStream) as AutoCompleteResponse; 
     memoryStream.Close(); 

     // Raise Event 
     this.OnSearchCompleted(
      new WhatEventArgs() 
      { 
       response = autocompleteSearchResponse 
      } 
     ); 
    }; 
    w.DownloadStringAsync(builder.Uri); 

Le retour que je crée présente comme suit:

public class WhatEventArgs : EventArgs 
    { 
     public AutoCompleteResponse response { get; set; } 
    } 

* edit: en ajoutant le code qui est utilisé pour obtenir les données ici Incase cela est utile ... Voilà comment je reçois les données à partir des valeurs, peut-être que je fais quelque chose de mal, mais je ne reçois pas de données (il est nul) et je ne sais pas ce que je l'ai fait mal *

protected void cmdSearch_Click(object sender, EventArgs e) 
    { 
     AutocompleteWhat search = new AutocompleteWhat() 
     { 
      Num = 2 
     }; 
     search.SearchCompleted += (a, b) => 
     { 
      List<values> _value = new List<values>(); 
      foreach (termHints item in b.response.hints) 
      { 
       _value.Add(item.Values); 
      } 
      if (_value.Count > 0) 
      { 
       dgvResults.DataSource = _value; 
      } 
      else 
      { 
       dgvResults.DataSource = null; 
      } 
      dgvResults.DataBind(); 
     }; 
     search.Search("plu"); 
    } 

Je dois maintenant obtenir les valeurs réelles des conseils, Cependant, les données renvoyées à partir des valeurs sont vides. Je n'ai aucune idée pourquoi, s'il vous plaît voir si vous pouvez voir ce que je ne peux pas voir.

modifier Correction du JSON, il manquait la fermeture] pour « facettes »

+2

Yo Dawg, je vous troupeau comme des listes, nous avons donc mis une liste dans votre liste afin que vous puissiez la liste pendant que vous listez – maxbeaudoin

+0

Pourriez-vous ajouter le code où vous faites réellement désérialisation, grâce – maxbeaudoin

+0

Le code a été ajouté ... J'aime les listes;) – Ghostfire

Répondre

0

Pour le DataContractJsonSerializer marche, vous devez avoir le système de type avec le schéma qui correspond à la JSON. Le champ "values" n'est pas une liste (ou un tableau) - c'est un autre objet JSON, donc vous n'avez pas besoin de le déclarer List<Value> - c'est juste un objet Value. De plus, les propriétés DataMember Name de la classe termHints sont définies sur 'Values' et 'Facets' pour leurs membres respectifs, mais dans le json les noms sont en minuscules, donc vous devrez changer cela aussi (DataMember (Name = "valeurs") et DataMember (Name = "facettes").

Mise à jour avec le code

Un autre problème que je vois dans le code/JSON est que dans le document JSON, facets est un frère de termHints, mais dans les contrats de données que vous avez, les facettes sont un enfant des indices, donc l'un de ces besoins doit être changé. Ci-dessous un code avec les deux versions , Juste choisir un :)

public class StackOverflow_6747339 
{ 
    class FacetsAsSiblingOfHints 
    { 
     [DataContract] 
     public class AutoCompleteResponse 
     { 
      [DataMember(Name = "parameters")] 
      public Parameter Parameters { get; set; } 
      [DataMember(Name = "termHints")] 
      public List<TermHints> Hints { get; set; } 
      [DataMember(Name = "facets")] 
      public List<Facets> Facets { get; set; } 
      [DataMember(Name = "total")] 
      public string Total { get; set; } 

      public override string ToString() 
      { 
       return string.Format("AutoCompleteResponse[Parameters={0},hints={1},facets={2},total={3}]", 
        Parameters, ListToString(Hints), ListToString(Facets), Total); 
      } 
     } 
     [DataContract] 
     public class Parameter 
     { 
      [DataMember(Name = "tbdb")] 
      public string tbdb { get; set; } 
      [DataMember(Name = "min_prefix_length")] 
      public string min_prefix_length { get; set; } 
      [DataMember(Name = "service")] 
      public string service { get; set; } 
      [DataMember(Name = "template")] 
      public string template { get; set; } 
      [DataMember(Name = "term_prefix")] 
      public string term_prefrix { get; set; } 

      public override string ToString() 
      { 
       return string.Format("Parameter[tbdb={0},min_prefix_length={1},service={2},template={3},term_prefix={4}]", 
        tbdb, min_prefix_length, service, template, term_prefrix); 
      } 
     } 
     [DataContract] 
     public class TermHints 
     { 
      [DataMember(Name = "name")] 
      public string Name { get; set; } 
      [DataMember(Name = "id")] 
      public string Id { get; set; } 
      [DataMember(Name = "values")] 
      public Values Values { get; set; } 

      public override string ToString() 
      { 
       return string.Format("TermHints[Name={0},Id={1},Values={2}]", Name, Id, Values); 
      } 
     } 
     [DataContract] 
     public class Values 
     { 
      [DataMember(Name = "value")] 
      public string value_name { get; set; } 
      [DataMember(Name = "pre_em")] 
      public string pre_em { get; set; } 
      [DataMember(Name = "em")] 
      public string em { get; set; } 
      [DataMember(Name = "post_em")] 
      public string post_em { get; set; } 
      [DataMember(Name = "nature")] 
      public string nature { get; set; } 
      [DataMember(Name = "id")] 
      public string value_id { get; set; } 

      public override string ToString() 
      { 
       return string.Format("Values[value_name={0},pre_em={1},em={2},post_em={3},nature={4},value_id={5}]", 
        value_name, pre_em, em, post_em, nature, value_id); 
      } 
     } 
     [DataContract] 
     public class Facets 
     { 
      [DataMember(Name = "id")] 
      public string facet_id { get; set; } 
      [DataMember(Name = "name")] 
      public string facet_name { get; set; } 

      public override string ToString() 
      { 
       return string.Format("Facets[facet_id={0},facet_name={1}]", facet_id, facet_name); 
      } 
     } 

     const string json = @"{ 
""parameters"": { 
    ""tbdb"": ""trudon"", 
    ""min_prefix_length"": ""2"", 
    ""service"": ""prefix"", 
    ""template"": ""service.json"", 
    ""term_prefix"": ""plu""}, 
""termHints"": [ 
    { 
     ""name"": ""Plumbers & Sanitary Engineers"", 
     ""id"":""209654"", 
     ""values"": { 
      ""value"":""Plumbers & Sanitary Engineers"", 
      ""pre_em"":"""", 
      ""em"":""Plu"", 
      ""post_em"":""mbers & Sanitary Engineers"", 
      ""nature"":""PT"", 
      ""id"":""209654"" 
     } 
    }, 
], 
""facets"": [ 
    { 
     ""id"":""209654"", 
     ""name"":""Plumbers & Sanitary Engineers"" 
    } 
], 
""total"":1 
}"; 

     internal static void Test() 
     { 
      Console.WriteLine("Facets as siblings of the hints"); 
      DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(AutoCompleteResponse)); 
      MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json)); 
      AutoCompleteResponse obj = (AutoCompleteResponse)dcjs.ReadObject(ms); 
      ms.Close(); 
      Console.WriteLine(obj); 
      Console.WriteLine(); 
     } 
    } 

    class FacetsInsideHints 
    { 
     [DataContract] 
     public class AutoCompleteResponse 
     { 
      [DataMember(Name = "parameters")] 
      public Parameter Parameters { get; set; } 
      [DataMember(Name = "termHints")] 
      public List<TermHints> Hints { get; set; } 
      [DataMember(Name = "total")] 
      public string Total { get; set; } 

      public override string ToString() 
      { 
       return string.Format("AutoCompleteResponse[Parameters={0},hints={1},total={2}]", 
        Parameters, ListToString(Hints), Total); 
      } 
     } 
     [DataContract] 
     public class Parameter 
     { 
      [DataMember(Name = "tbdb")] 
      public string tbdb { get; set; } 
      [DataMember(Name = "min_prefix_length")] 
      public string min_prefix_length { get; set; } 
      [DataMember(Name = "service")] 
      public string service { get; set; } 
      [DataMember(Name = "template")] 
      public string template { get; set; } 
      [DataMember(Name = "term_prefix")] 
      public string term_prefrix { get; set; } 

      public override string ToString() 
      { 
       return string.Format("Parameter[tbdb={0},min_prefix_length={1},service={2},template={3},term_prefix={4}]", 
        tbdb, min_prefix_length, service, template, term_prefrix); 
      } 
     } 
     [DataContract] 
     public class TermHints 
     { 
      [DataMember(Name = "name")] 
      public string Name { get; set; } 
      [DataMember(Name = "id")] 
      public string Id { get; set; } 
      [DataMember(Name = "values")] 
      public Values Values { get; set; } 
      [DataMember(Name = "facets")] 
      public List<Facets> Facets { get; set; } 

      public override string ToString() 
      { 
       return string.Format("TermHints[Name={0},Id={1},Values={2},Facets={3}]", Name, Id, Values, ListToString(Facets)); 
      } 
     } 
     [DataContract] 
     public class Values 
     { 
      [DataMember(Name = "value")] 
      public string value_name { get; set; } 
      [DataMember(Name = "pre_em")] 
      public string pre_em { get; set; } 
      [DataMember(Name = "em")] 
      public string em { get; set; } 
      [DataMember(Name = "post_em")] 
      public string post_em { get; set; } 
      [DataMember(Name = "nature")] 
      public string nature { get; set; } 
      [DataMember(Name = "id")] 
      public string value_id { get; set; } 

      public override string ToString() 
      { 
       return string.Format("Values[value_name={0},pre_em={1},em={2},post_em={3},nature={4},value_id={5}]", 
        value_name, pre_em, em, post_em, nature, value_id); 
      } 
     } 
     [DataContract] 
     public class Facets 
     { 
      [DataMember(Name = "id")] 
      public string facet_id { get; set; } 
      [DataMember(Name = "name")] 
      public string facet_name { get; set; } 

      public override string ToString() 
      { 
       return string.Format("Facets[facet_id={0},facet_name={1}]", facet_id, facet_name); 
      } 
     } 

     const string json = @"{ 
""parameters"": { 
    ""tbdb"": ""trudon"", 
    ""min_prefix_length"": ""2"", 
    ""service"": ""prefix"", 
    ""template"": ""service.json"", 
    ""term_prefix"": ""plu""}, 
""termHints"": [ 
    { 
     ""name"": ""Plumbers & Sanitary Engineers"", 
     ""id"":""209654"", 
     ""values"": { 
      ""value"":""Plumbers & Sanitary Engineers"", 
      ""pre_em"":"""", 
      ""em"":""Plu"", 
      ""post_em"":""mbers & Sanitary Engineers"", 
      ""nature"":""PT"", 
      ""id"":""209654"" 
     }, 
     ""facets"": [ 
      { 
       ""id"":""209654"", 
       ""name"":""Plumbers & Sanitary Engineers"" 
      } 
     ] 
    }, 
], 
""total"":1 
}"; 

     internal static void Test() 
     { 
      Console.WriteLine("Facets inside the hints"); 
      DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(AutoCompleteResponse)); 
      MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json)); 
      AutoCompleteResponse obj = (AutoCompleteResponse)dcjs.ReadObject(ms); 
      ms.Close(); 
      Console.WriteLine(obj); 
      Console.WriteLine(); 
     } 
    } 

    static string ListToString<T>(List<T> list) 
    { 
     if (list == null) 
     { 
      return "<<null>>"; 
     } 

     StringBuilder sb = new StringBuilder(); 
     sb.Append("["); 
     for (int i = 0; i < list.Count; i++) 
     { 
      if (i > 0) sb.Append(","); 
      sb.Append(list[i]); 
     } 

     sb.Append("]"); 
     return sb.ToString(); 
    } 

    public static void Test() 
    { 
     FacetsAsSiblingOfHints.Test(); 
     FacetsInsideHints.Test(); 
    } 
} 
+0

Ok, j'ai fait les changements suggérés au code, j'ai un peu mal compris ce que vous avez suggéré initialement mais je l'ai compris après une tasse de café. Le problème est maintenant que la classe de valeur ne renvoie aucun résultat, tout est vide ... aucune idée pourquoi? Si près d'une solution, ça va probablement me gifler au visage .. J'ai mis à jour le code .. devrait probablement changer le titre aussi .. – Ghostfire