209

I'm trying to parse some JSON data from the Google AJAX Search API. I have this URL and I'd like to break it down so that the results are displayed. I've currently written this code, but I'm pretty lost in regards of what to do next, although there are a number of examples out there with simplified JSON strings.

Being new to C# and .NET in general I've struggled to get a genuine text output for my ASP.NET page so I've been recommended to give JSON.NET a try. Could anyone point me in the right direction to just simply writing some code that'll take in JSON from the Google AJAX Search API and print it out to the screen?


EDIT: ALL FIXED! All results are working fine. Thank you again 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; }
    }
}

The code currently compiles and runs perfectly, but isn't returning any results. Could someone help me with returning what I require, the results ready to print out to the screen?

Edit:

Json.NET works using the same JSON and classes as the example above.

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

Link: Serializing and Deserializing JSON with Json.NET

Related

C# - parsing json formatted data into nested hashtables
Parse JSON array

3
  • Your GoogleSearchResults type has fields and properties that have the same name. Try renaming your fields with leading underscores (anything that will disambiguate between the two). Jul 31, 2009 at 16:13
  • 3
    I've had good results with json.net james.newtonking.com/pages/json-net.aspx
    – kenny
    Aug 2, 2009 at 14:25
  • 2
    I would second @kenny above. The .NET JSON serializer has absolutely terrible performance compared to JSON.NET. Jun 14, 2011 at 18:45

7 Answers 7

153
+300

[Update]
I've just realized why you weren't receiving results back... you have a missing line in your Deserialize method. You were forgetting to assign the results to your obj :

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

Also, just for reference, here is the Serialize method :

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());
    }
}

Edit

If you want to use Json.NET here are the equivalent Serialize/Deserialize methods to the code above..

Deserialize:

JsonConvert.DeserializeObject<T>(string json);

Serialize:

JsonConvert.SerializeObject(object o);

This are already part of Json.NET so you can just call them on the JsonConvert class.

Link: Serializing and Deserializing JSON with Json.NET



Now, the reason you're getting a StackOverflow is because of your Properties.

Take for example this one :

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

Notice that in the getter, you are returning the actual property (ie the property's getter is calling itself over and over again), and thus you are creating an infinite recursion.


Properties (in 2.0) should be defined like such :

string _unescapedUrl; // <= private field

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

You have a private field and then you return the value of that field in the getter, and set the value of that field in the setter.


Btw, if you're using the 3.5 Framework, you can just do this and avoid the backing fields, and let the compiler take care of that :

public string unescapedUrl { get; set;}
6
  • As far as I am aware this machine hasn't been updated to 3.5 yet, so I assume 2.0. I've already tried the get/set thing and it didn't work, but that part seems to be working great.
    – Mike B
    Aug 2, 2009 at 14:46
  • ...hmm, but if I'm not mistaken, the DataContractJsonSerializer is available only in the 3.5 framework, no ? Aug 2, 2009 at 14:57
  • That's odd, because Visual Studio doesn't seem to have a problem with recognising DataContractJsonSerializer in my code, yet it doesn't like using (get; set;).
    – Mike B
    Aug 2, 2009 at 14:57
  • Either way, I've upgraded this new machine to 3.5, so there shouldn't be any problems.
    – Mike B
    Aug 2, 2009 at 14:58
  • I've added this extra line of code and if I try to write g1.responseData.results I get "results[]" printed to my screen, with everything else printing as their names (e.g. g1.responseData printing "responseData" and g1 printing "GoogleSearchResults").
    – Mike B
    Aug 2, 2009 at 16:53
16

I found this approach which parse JSON into a dynamic object, it extends a DynamicObject and JavascriptConverter to turn the string into an object.

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);
    }
}

Converter

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) })); }
    }
}

Usage (sample 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);
}

This method has to return true, otherwise it will throw an error. E.g. you can throw an error if a key does not exist.

Returning true and emptying result will return an empty value rather than throwing an error.

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);
}
15

Your data class doesn't match the JSON object. Use this instead:

[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; }
}

Also, you don't have to instantiate the class to get its type for deserialization:

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);
    }
}
3
  • I've just tried that, but I've just got the error "The type or namespace name 'IEnumerable' could not be found (are you missing a using directive or an assembly reference?)".
    – Mike B
    Aug 2, 2009 at 15:00
  • Nevermind, I was using System.Collections instead of System.Collection.Generic. It compiles perfectly with that code now, but what do I need to do to output the data?
    – Mike B
    Aug 2, 2009 at 15:10
  • Check my updated post because I found what was missing in your code Aug 2, 2009 at 15:11
8

I just think the whole example would be useful. This is the example for this problem.

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; }
}
6

I tried to use the code above but didn't work. The JSON structure returned by Google is so different and there is a very important miss in the helper function: a call to DataContractJsonSerializer.ReadObject() that actually deserializes the JSON data into the object.

Here is the code that WORKS in 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; }
    }
}

To get the content of the first result, do:

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

Thank you all for your help. This is my final version, and it works thanks to your combined help ! I am only showing the changes i made, all the rest is taken from Joe Chung's work

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

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

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

and

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

Google Map API request and parse DirectionsResponse with C#, change the json in your url to xml and use the following code to turn the result into a usable C# Generic List Object.

Took me a while to make. But here it is

var url = String.Format("http://maps.googleapis.com/maps/api/directions/xml?...");
var result = new System.Net.WebClient().DownloadString(url);
var doc = XDocument.Load(new StringReader(result));

var DirectionsResponse = doc.Elements("DirectionsResponse").Select(l => new
{
    Status = l.Elements("status").Select(q => q.Value).FirstOrDefault(),
    Route = l.Descendants("route").Select(n => new
    {
        Summary = n.Elements("summary").Select(q => q.Value).FirstOrDefault(),
        Leg = n.Elements("leg").ToList().Select(o => new
        {
            Step = o.Elements("step").Select(p => new
            {
                Travel_Mode = p.Elements("travel_mode").Select(q => q.Value).FirstOrDefault(),
                Start_Location = p.Elements("start_location").Select(q => new
                {
                    Lat = q.Elements("lat").Select(r => r.Value).FirstOrDefault(),
                    Lng = q.Elements("lng").Select(r => r.Value).FirstOrDefault()
                }).FirstOrDefault(),
                End_Location = p.Elements("end_location").Select(q => new
                {
                    Lat = q.Elements("lat").Select(r => r.Value).FirstOrDefault(),
                    Lng = q.Elements("lng").Select(r => r.Value).FirstOrDefault()
                }).FirstOrDefault(),
                Polyline = p.Elements("polyline").Select(q => new
                {
                    Points = q.Elements("points").Select(r => r.Value).FirstOrDefault()
                }).FirstOrDefault(),
                Duration = p.Elements("duration").Select(q => new
                {
                    Value = q.Elements("value").Select(r => r.Value).FirstOrDefault(),
                    Text = q.Elements("text").Select(r => r.Value).FirstOrDefault(),
                }).FirstOrDefault(),
                Html_Instructions = p.Elements("html_instructions").Select(q => q.Value).FirstOrDefault(),
                Distance = p.Elements("distance").Select(q => new
                {
                    Value = q.Elements("value").Select(r => r.Value).FirstOrDefault(),
                    Text = q.Elements("text").Select(r => r.Value).FirstOrDefault(),
                }).FirstOrDefault()
            }).ToList(),
            Duration = o.Elements("duration").Select(p => new
            {
                Value = p.Elements("value").Select(q => q.Value).FirstOrDefault(),
                Text = p.Elements("text").Select(q => q.Value).FirstOrDefault()
            }).FirstOrDefault(),
            Distance = o.Elements("distance").Select(p => new
            {
                Value = p.Elements("value").Select(q => q.Value).FirstOrDefault(),
                Text = p.Elements("text").Select(q => q.Value).FirstOrDefault()
            }).FirstOrDefault(),
            Start_Location = o.Elements("start_location").Select(p => new
            {
                Lat = p.Elements("lat").Select(q => q.Value).FirstOrDefault(),
                Lng = p.Elements("lng").Select(q => q.Value).FirstOrDefault()
            }).FirstOrDefault(),
            End_Location = o.Elements("end_location").Select(p => new
            {
                Lat = p.Elements("lat").Select(q => q.Value).FirstOrDefault(),
                Lng = p.Elements("lng").Select(q => q.Value).FirstOrDefault()
            }).FirstOrDefault(),
            Start_Address = o.Elements("start_address").Select(q => q.Value).FirstOrDefault(),
            End_Address = o.Elements("end_address").Select(q => q.Value).FirstOrDefault()
        }).ToList(),
        Copyrights = n.Elements("copyrights").Select(q => q.Value).FirstOrDefault(),
        Overview_polyline = n.Elements("overview_polyline").Select(q => new
        {
            Points = q.Elements("points").Select(r => r.Value).FirstOrDefault()
        }).FirstOrDefault(),
        Waypoint_Index = n.Elements("waypoint_index").Select(o => o.Value).ToList(),
        Bounds = n.Elements("bounds").Select(q => new
        {
            SouthWest = q.Elements("southwest").Select(r => new
            {
                Lat = r.Elements("lat").Select(s => s.Value).FirstOrDefault(),
                Lng = r.Elements("lng").Select(s => s.Value).FirstOrDefault()
            }).FirstOrDefault(),
            NorthEast = q.Elements("northeast").Select(r => new
            {
                Lat = r.Elements("lat").Select(s => s.Value).FirstOrDefault(),
                Lng = r.Elements("lng").Select(s => s.Value).FirstOrDefault()
            }).FirstOrDefault(),
        }).FirstOrDefault()
    }).FirstOrDefault()
}).FirstOrDefault();

I hope this will help someone.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.