204 votes

Parser JSON en C#

Je suis en train d'analyser certaines données JSON à partir de Google AJAX Search API. J'ai cette URL , et j'aimerais les casser vers le bas de sorte que les résultats sont affichés. J'ai actuellement écrit ce code, mais je suis assez perdu en ce qui concerne les choses à faire à côté, bien qu'il existe un certain nombre d'exemples simplifiés de chaînes JSON.

Étant novice en C# et .NET en général, j'ai eu du mal à obtenir une véritable sortie de texte pour mon ASP.NET la page j'ai donc été recommandé de donner JSON.NET un essai. Quelqu'un pourrait-il me diriger dans la bonne direction pour simplement écrire du code qui va prendre en JSON à partir de Google AJAX Search API et l'imprimer à l'écran?


EDIT: TOUS LES FIXES! Tous les résultats sont à travailler. Merci encore Dreas Grech!

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.ServiceModel.Web;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Text;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        GoogleSearchResults g1 = new GoogleSearchResults();
        const string json = @"{""responseData"": {""results"":[{""GsearchResultClass"":""GwebSearch"",""unescapedUrl"":""http://www.cheese.com/"",""url"":""http://www.cheese.com/"",""visibleUrl"":""www.cheese.com"",""cacheUrl"":""http://www.google.com/search?q\u003dcache:bkg1gwNt8u4J:www.cheese.com"",""title"":""\u003cb\u003eCHEESE\u003c/b\u003e.COM - All about \u003cb\u003echeese\u003c/b\u003e!."",""titleNoFormatting"":""CHEESE.COM - All about cheese!."",""content"":""\u003cb\u003eCheese\u003c/b\u003e - everything you want to know about it. Search \u003cb\u003echeese\u003c/b\u003e by name, by types   of milk, by textures and by countries.""},{""GsearchResultClass"":""GwebSearch"",""unescapedUrl"":""http://en.wikipedia.org/wiki/Cheese"",""url"":""http://en.wikipedia.org/wiki/Cheese"",""visibleUrl"":""en.wikipedia.org"",""cacheUrl"":""http://www.google.com/search?q\u003dcache:n9icdgMlCXIJ:en.wikipedia.org"",""title"":""\u003cb\u003eCheese\u003c/b\u003e - Wikipedia, the free encyclopedia"",""titleNoFormatting"":""Cheese - Wikipedia, the free encyclopedia"",""content"":""\u003cb\u003eCheese\u003c/b\u003e is a food consisting of proteins and fat from milk, usually the milk of   cows, buffalo, goats, or sheep. It is produced by coagulation of the milk \u003cb\u003e...\u003c/b\u003e""},{""GsearchResultClass"":""GwebSearch"",""unescapedUrl"":""http://www.ilovecheese.com/"",""url"":""http://www.ilovecheese.com/"",""visibleUrl"":""www.ilovecheese.com"",""cacheUrl"":""http://www.google.com/search?q\u003dcache:GBhRR8ytMhQJ:www.ilovecheese.com"",""title"":""I Love \u003cb\u003eCheese\u003c/b\u003e!, Homepage"",""titleNoFormatting"":""I Love Cheese!, Homepage"",""content"":""The American Dairy Association\u0026#39;s official site includes recipes and information   on nutrition and storage of \u003cb\u003echeese\u003c/b\u003e.""},{""GsearchResultClass"":""GwebSearch"",""unescapedUrl"":""http://www.gnome.org/projects/cheese/"",""url"":""http://www.gnome.org/projects/cheese/"",""visibleUrl"":""www.gnome.org"",""cacheUrl"":""http://www.google.com/search?q\u003dcache:jvfWnVcSFeQJ:www.gnome.org"",""title"":""\u003cb\u003eCheese\u003c/b\u003e"",""titleNoFormatting"":""Cheese"",""content"":""\u003cb\u003eCheese\u003c/b\u003e uses your webcam to take photos and videos, applies fancy special effects   and lets you share the fun with others. It was written as part of Google\u0026#39;s \u003cb\u003e...\u003c/b\u003e""}],""cursor"":{""pages"":[{""start"":""0"",""label"":1},{""start"":""4"",""label"":2},{""start"":""8"",""label"":3},{""start"":""12"",""label"":4},{""start"":""16"",""label"":5},{""start"":""20"",""label"":6},{""start"":""24"",""label"":7},{""start"":""28"",""label"":8}],""estimatedResultCount"":""14400000"",""currentPageIndex"":0,""moreResultsUrl"":""http://www.google.com/search?oe\u003dutf8\u0026ie\u003dutf8\u0026source\u003duds\u0026start\u003d0\u0026hl\u003den-GB\u0026q\u003dcheese""}}, ""responseDetails"": null, ""responseStatus"": 200}";
        g1 = JSONHelper.Deserialise<GoogleSearchResults>(json);
        Response.Write(g1.content);
    }
}

public class JSONHelper
{
    public static T Deserialise<T>(string json)
    {
        T obj = Activator.CreateInstance<T>();
        MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
        DataContractJsonSerializer serialiser = new DataContractJsonSerializer(obj.GetType());
        ms.Close();
        return obj;
    }
}
/// Deserialise from JSON
[Serializable]
public class GoogleSearchResults
{
    public GoogleSearchResults() { }
    public GoogleSearchResults(string _unescapedUrl, string _url, string _visibleUrl, string _cacheUrl, string _title, string _titleNoFormatting, string _content)
    {
        this.unescapedUrl = _unescapedUrl;
        this.url = _url;
        this.visibleUrl = _visibleUrl;
        this.cacheUrl = _cacheUrl;
        this.title = _title;
        this.titleNoFormatting = _titleNoFormatting;
        this.content = _content;
    }

    string _unescapedUrl;
    string _url;
    string _visibleUrl;
    string _cacheUrl;
    string _title;
    string _titleNoFormatting;
    string _content;

    [DataMember]
    public string unescapedUrl
    {
        get { return _unescapedUrl; }
        set { _unescapedUrl = value; }
    }

    [DataMember]
    public string url
    {
        get { return _url; }
        set { _url = value; }
    }

    [DataMember]
    public string visibleUrl
    {
        get { return _visibleUrl; }
        set { _visibleUrl = value; }
    }
    [DataMember]
    public string cacheUrl
    {
        get { return _cacheUrl; }
        set { _cacheUrl = value; }
    }

    [DataMember]
    public string title
    {
        get { return _title; }
        set { _title = value; }
    }

    [DataMember]
    public string titleNoFormatting
    {
        get { return _titleNoFormatting; }
        set { _titleNoFormatting = value; }
    }

    [DataMember]
    public string content
    {
        get { return _content; }
        set { _content = value; }
    }
}

Le code compile et s'exécute parfaitement, mais ne renvoie aucun résultat. Quelqu'un pourrait m'aider avec le retour de ce que j'ai besoin, les résultats prête à être imprimée à l'écran?

Edit:

Json.NET fonctionne à l'aide du même JSON et les classes comme dans l'exemple ci-dessus.

GoogleSearchResults g1 = JsonConvert.DeserializeObject<GoogleSearchResults>(json);

Lien: la Sérialisation et la Désérialisation de JSON avec Json.NET

Liées

C# - l'analyse des données au format json dans imbriqués les tables de hashage
Analyser tableau JSON

150voto

Andreas Grech Points 39188

[Mise à jour]
Je viens de réaliser pourquoi vous n'avez pas de recevoir des résultats... vous avez une ligne manquante dans votre Deserialize méthode. Vous étiez oublier d'attribuer les résultats à votre obj :

public static T Deserialise<T>(string json)
{
    T obj = Activator.CreateInstance<T>();
    using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
    {
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
        obj = (T)serializer.ReadObject(ms); // <== Your missing line
        return obj;
    } 
}

Aussi, juste pour la référence, ici, c'est l' Serialize méthode :

public static string Serialize<T>(T obj)
{
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
    using (MemoryStream ms = new MemoryStream())
    {
        serializer.WriteObject(ms, obj);
        return Encoding.Default.GetString(ms.ToArray());
    }
}

Modifier

Si vous souhaitez utiliser Json.NET voici l'équivalent de Sérialiser/Désérialiser des méthodes pour le code ci-dessus..

Désérialiser:

JsonConvert.DeserializeObject<T>(string json);

Sérialiser:

JsonConvert.SerializeObject(object o);

Ce sont déjà de la partie de Json.NET ainsi, vous pouvez simplement appeler sur le JsonConvert classe.

Lien: la Sérialisation et la Désérialisation de JSON avec Json.NET



Maintenant, la raison pour laquelle vous êtes l'obtention d'un StackOverflow est à cause de votre Properties.

Prenez par exemple celui-ci :

[DataMember]
public string unescapedUrl
{
    get { return unescapedUrl; } // <= this line is causing a Stack Overflow
    set { this.unescapedUrl = value; }
}

Notez que dans l' getter, vous êtes de retour la propriété réelle (c'est à dire la propriété du getter est d'appeler lui-même maintes et maintes fois), et donc de la création d'une récursion infinie.


Propriétés (en 2.0) doit être défini comme tel :

string _unescapedUrl; // <= private field

[DataMember]
public string unescapedUrl
{
    get { return _unescapedUrl; } 
    set { _unescapedUrl = value; }
}

Vous avez un domaine privé et ensuite vous retourner la valeur de ce champ dans la lecture, et de définir la valeur de ce champ dans l'incubateur.


Btw, si vous utilisez le Framework 3.5, vous pouvez simplement le faire et éviter les champs de sauvegarde, et laisser le compilateur prendre soin de cela :

public string unescapedUrl { get; set;}

15voto

Joe Chung Points 6263

Vos données de classe ne correspond pas à l'objet JSON. Utilisez ceci à la place:

[DataContract]
public class GoogleSearchResults
{
    [DataMember]
    public ResponseData responseData { get; set; }
}

[DataContract]
public class ResponseData
{
    [DataMember]
    public IEnumerable<Results> results { get; set; }
}

[DataContract]
public class Results
{
    [DataMember]
    public string unescapedUrl { get; set; }

    [DataMember]
    public string url { get; set; }

    [DataMember]
    public string visibleUrl { get; set; }

    [DataMember]
    public string cacheUrl { get; set; }

    [DataMember]
    public string title { get; set; }

    [DataMember]
    public string titleNoFormatting { get; set; }

    [DataMember]
    public string content { get; set; }
}

Aussi, vous n'avez pas à instancier la classe pour obtenir son type pour la désérialisation:

public static T Deserialise<T>(string json)
{
    using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
    {
        var serialiser = new DataContractJsonSerializer(typeof(T));
        return (T)serialiser.ReadObject(ms);
    }
}

15voto

BrunoLM Points 26573

J'ai trouvé cette approche qui parser JSON en un objet dynamique, il prolonge DynamicObject et JavascriptConverter de transformer la chaîne de caractères dans un objet.

DynamicJsonObject

public class DynamicJsonObject : DynamicObject
{
    private IDictionary<string, object> Dictionary { get; set; }

    public DynamicJsonObject(IDictionary<string, object> dictionary)
    {
        this.Dictionary = dictionary;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        result = this.Dictionary[binder.Name];

        if (result is IDictionary<string, object>)
        {
            result = new DynamicJsonObject(result as IDictionary<string, object>);
        }
        else if (result is ArrayList && (result as ArrayList) is IDictionary<string, object>)
        {
            result = new List<DynamicJsonObject>((result as ArrayList).ToArray().Select(x => new DynamicJsonObject(x as IDictionary<string, object>)));
        }
        else if (result is ArrayList)
        {
            result = new List<object>((result as ArrayList).ToArray());
        }

        return this.Dictionary.ContainsKey(binder.Name);
    }
}

Convertisseur

public class DynamicJsonConverter : JavaScriptConverter
{
    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        if (dictionary == null)
            throw new ArgumentNullException("dictionary");

        if (type == typeof(object))
        {
            return new DynamicJsonObject(dictionary);
        }

        return null;
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override IEnumerable<Type> SupportedTypes
    {
        get { return new ReadOnlyCollection<Type>(new List<Type>(new Type[] { typeof(object) })); }
    }
}

Utilisation (parexemple json):

JavaScriptSerializer jss = new JavaScriptSerializer();
jss.RegisterConverters(new JavaScriptConverter[] { new DynamicJsonConverter() });

dynamic glossaryEntry = jss.Deserialize(json, typeof(object)) as dynamic;

Console.WriteLine("glossaryEntry.glossary.title: " + glossaryEntry.glossary.title);
Console.WriteLine("glossaryEntry.glossary.GlossDiv.title: " + glossaryEntry.glossary.GlossDiv.title);
Console.WriteLine("glossaryEntry.glossary.GlossDiv.GlossList.GlossEntry.ID: " + glossaryEntry.glossary.GlossDiv.GlossList.GlossEntry.ID);
Console.WriteLine("glossaryEntry.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.para: " + glossaryEntry.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.para);
foreach (var also in glossaryEntry.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso)
{
    Console.WriteLine("glossaryEntry.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso: " + also);
}

Cette méthode doit retourner true, sinon il renvoie une erreur. E. g. vous pouvez lever une erreur si une clé n'existe pas.

De retour true et vider result renverra une valeur vide plutôt que de jeter une erreur.

public override bool TryGetMember(GetMemberBinder binder, out object result)
{

    if (!this.Dictionary.ContainsKey(binder.Name))
    {
        result = "";
    }
    else
    {
        result = this.Dictionary[binder.Name];
    }

    if (result is IDictionary<string, object>)
    {
        result = new DynamicJsonObject(result as IDictionary<string, object>);
    }
    else if (result is ArrayList && (result as ArrayList) is IDictionary<string, object>)
    {
        result = new List<DynamicJsonObject>((result as ArrayList).ToArray().Select(x => new DynamicJsonObject(x as IDictionary<string, object>)));
    }
    else if (result is ArrayList)
    {
        result = new List<object>((result as ArrayList).ToArray());
    }

    return true; // this.Dictionary.ContainsKey(binder.Name);
}

8voto

mamezcua Points 41

Je pense juste que l'ensemble de l'exemple serait utile. C'est l'exemple de ce problème.

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.ServiceModel.Web;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Text;
using System.Collections.Generic;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        GoogleSearchResults g1 = new GoogleSearchResults();
        const string json = @"{""responseData"": {""results"":[{""GsearchResultClass"":""GwebSearch"",""unescapedUrl"":""http://www.cheese.com/"",""url"":""http://www.cheese.com/"",""visibleUrl"":""www.cheese.com"",""cacheUrl"":""http://www.google.com/search?q\u003dcache:bkg1gwNt8u4J:www.cheese.com"",""title"":""\u003cb\u003eCHEESE\u003c/b\u003e.COM - All about \u003cb\u003echeese\u003c/b\u003e!."",""titleNoFormatting"":""CHEESE.COM - All about cheese!."",""content"":""\u003cb\u003eCheese\u003c/b\u003e - everything you want to know about it. Search \u003cb\u003echeese\u003c/b\u003e by name, by types   of milk, by textures and by countries.""},{""GsearchResultClass"":""GwebSearch"",""unescapedUrl"":""http://en.wikipedia.org/wiki/Cheese"",""url"":""http://en.wikipedia.org/wiki/Cheese"",""visibleUrl"":""en.wikipedia.org"",""cacheUrl"":""http://www.google.com/search?q\u003dcache:n9icdgMlCXIJ:en.wikipedia.org"",""title"":""\u003cb\u003eCheese\u003c/b\u003e - Wikipedia, the free encyclopedia"",""titleNoFormatting"":""Cheese - Wikipedia, the free encyclopedia"",""content"":""\u003cb\u003eCheese\u003c/b\u003e is a food consisting of proteins and fat from milk, usually the milk of   cows, buffalo, goats, or sheep. It is produced by coagulation of the milk \u003cb\u003e...\u003c/b\u003e""},{""GsearchResultClass"":""GwebSearch"",""unescapedUrl"":""http://www.ilovecheese.com/"",""url"":""http://www.ilovecheese.com/"",""visibleUrl"":""www.ilovecheese.com"",""cacheUrl"":""http://www.google.com/search?q\u003dcache:GBhRR8ytMhQJ:www.ilovecheese.com"",""title"":""I Love \u003cb\u003eCheese\u003c/b\u003e!, Homepage"",""titleNoFormatting"":""I Love Cheese!, Homepage"",""content"":""The American Dairy Association\u0026#39;s official site includes recipes and information   on nutrition and storage of \u003cb\u003echeese\u003c/b\u003e.""},{""GsearchResultClass"":""GwebSearch"",""unescapedUrl"":""http://www.gnome.org/projects/cheese/"",""url"":""http://www.gnome.org/projects/cheese/"",""visibleUrl"":""www.gnome.org"",""cacheUrl"":""http://www.google.com/search?q\u003dcache:jvfWnVcSFeQJ:www.gnome.org"",""title"":""\u003cb\u003eCheese\u003c/b\u003e"",""titleNoFormatting"":""Cheese"",""content"":""\u003cb\u003eCheese\u003c/b\u003e uses your webcam to take photos and videos, applies fancy special effects   and lets you share the fun with others. It was written as part of Google\u0026#39;s \u003cb\u003e...\u003c/b\u003e""}],""cursor"":{""pages"":[{""start"":""0"",""label"":1},{""start"":""4"",""label"":2},{""start"":""8"",""label"":3},{""start"":""12"",""label"":4},{""start"":""16"",""label"":5},{""start"":""20"",""label"":6},{""start"":""24"",""label"":7},{""start"":""28"",""label"":8}],""estimatedResultCount"":""14400000"",""currentPageIndex"":0,""moreResultsUrl"":""http://www.google.com/search?oe\u003dutf8\u0026ie\u003dutf8\u0026source\u003duds\u0026start\u003d0\u0026hl\u003den-GB\u0026q\u003dcheese""}}, ""responseDetails"": null, ""responseStatus"": 200}";
        g1 = JSONHelper.Deserialise<GoogleSearchResults>(json);

        foreach (Pages x in g1.responseData.cursor.pages)
        {
            // Anything you want to get
            Response.Write(x.label);

        }
    }
}

public class JSONHelper
{
    public static T Deserialise<T>(string json)
    {
        using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
        {
            var serialiser = new DataContractJsonSerializer(typeof(T));
            return (T)serialiser.ReadObject(ms);
        }
    }

    public static string Serialize<T>(T obj)
    {
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
        using (MemoryStream ms = new MemoryStream())
        {
            serializer.WriteObject(ms, obj);
            return Encoding.Default.GetString(ms.ToArray());
        }
    }
}

[DataContract]
public class GoogleSearchResults
{
    [DataMember]
    public ResponseData responseData { get; set; }

    [DataMember]
    public string responseStatus { get; set; }

}


public class ResponseData
{
    [DataMember]
    public Cursor cursor { get; set; }

    [DataMember]
    public IEnumerable<Results> results { get; set; }


}


[DataContract]
public class Cursor
{
    [DataMember]
    public IEnumerable<Pages> pages { get; set; }
}



[DataContract]
public class Pages
{
    [DataMember]
    public string start { get; set; }

    [DataMember]
    public string label { get; set; }

}


[DataContract]
public class Results
{
    [DataMember]
    public string unescapedUrl { get; set; }

    [DataMember]
    public string url { get; set; }

    [DataMember]
    public string visibleUrl { get; set; }

    [DataMember]
    public string cacheUrl { get; set; }

    [DataMember]
    public string title { get; set; }

    [DataMember]
    public string titleNoFormatting { get; set; }

    [DataMember]
    public string content { get; set; }
}

6voto

Martin Dimitrov Points 1843

J'ai essayé d'utiliser le code ci-dessus mais n'a pas fonctionné. La structure JSON renvoyé par Google est si différent et il est très important de miss dans la fonction d'assistance: un appel à l' DataContractJsonSerializer.ReadObject() qui fait désérialise les données JSON en objet.

Voici le code qui FONCTIONNE en 2011:

using System;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Text;
using System.Collections.Generic;

namespace <YOUR_NAMESPACE>
{
    public class JSONHelper
    {
        public static T Deserialise<T>(string json)
        {
            T obj = Activator.CreateInstance<T>();
            MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
            DataContractJsonSerializer serialiser = new DataContractJsonSerializer(obj.GetType());
            obj = (T)serialiser.ReadObject(ms);
            ms.Close();
            return obj;
        }
    }

    public class Result
    {
        public string GsearchResultClass { get; set; }
        public string unescapedUrl { get; set; }
        public string url { get; set; }
        public string visibleUrl { get; set; }
        public string cacheUrl { get; set; }
        public string title { get; set; }
        public string titleNoFormatting { get; set; }
        public string content { get; set; }
    }

    public class Page
    {
        public string start { get; set; }
        public int label { get; set; }
    }

    public class Cursor
    {
        public string resultCount { get; set; }
        public Page[] pages { get; set; }
        public string estimatedResultCount { get; set; }
        public int currentPageIndex { get; set; }
        public string moreResultsUrl { get; set; }
        public string searchResultTime { get; set; }
    }

    public class ResponseData
    {
        public Result[] results { get; set; }
        public Cursor cursor { get; set; }
    }

    public class GoogleSearchResults
    {
        public ResponseData responseData { get; set; }
        public object responseDetails { get; set; }
        public int responseStatus { get; set; }
    }
}

Pour obtenir le contenu de la première suite, faire:

GoogleSearchResults googleResults = new GoogleSearchResults();
googleResults = JSONHelper.Deserialise<GoogleSearchResults>(jsonData);
string contentOfFirstResult = googleResults.responseData.results[0].content;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X