在 C# 中解析 JSON

Posted

技术标签:

【中文标题】在 C# 中解析 JSON【英文标题】:Parse JSON in C# 【发布时间】:2010-11-15 18:56:02 【问题描述】:

我正在尝试从 Google AJAX 搜索 API 解析一些 JSON 数据。我有this URL,我想将其分解以便显示结果。我目前已经编写了这段代码,但是对于下一步该做什么我很迷茫,尽管有许多简化 JSON 字符串的示例。

一般来说,作为 C# 和 .NET 的新手,我一直在努力为我的 ASP.NET 页面获得真正的文本输出,因此建议我尝试 JSON.NET。谁能指出我正确的方向,只需编写一些从 Google AJAX 搜索 API 接收 JSON 并将其打印到屏幕上的代码?


编辑:全部修复!所有结果都运行良好。再次感谢 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; 
    

代码当前可以完美编译和运行,但没有返回任何结果。有人可以帮我返回我需要的东西,准备好打印到屏幕上的结果吗?

编辑:

Json.NET 使用与上述示例相同的 JSON 和类。

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

链接:Serializing and Deserializing JSON with Json.NET

相关

C# - parsing json formatted data into nested hashtablesParse JSON array

【问题讨论】:

您的GoogleSearchResults 类型具有同名的字段和属性。尝试使用前导下划线重命名您的字段(任何可以消除两者之间歧义的内容)。 我在 json.net james.newtonking.com/pages/json-net.aspx 上取得了不错的成绩 我会在上面提到@kenny。与 JSON.NET 相比,.NET JSON 序列化程序的性能绝对糟糕。 【参考方案1】:

[更新] 我刚刚意识到为什么您没有收到结果……您的 Deserialize 方法中缺少一行。您忘记将结果分配给您的 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);
     

另外,仅供参考,这里是Serialize方法:

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


编辑

如果你想使用 Json.NET,这里有与上面代码等效的 Serialize/Deserialize 方法..

反序列化:

JsonConvert.DeserializeObject<T>(string json);

序列化:

JsonConvert.SerializeObject(object o);

这已经是 Json.NET 的一部分,因此您可以在 JsonConvert 类上调用它们。

链接:Serializing and Deserializing JSON with Json.NET


现在,您获得 *** 的原因是因为您的 Properties

以这个为例:

[DataMember]
public string unescapedUrl

    get  return unescapedUrl;  // <= this line is causing a Stack Overflow
    set  this.unescapedUrl = value; 

请注意,在getter 中,您正在返回实际属性(即,该属性的 getter 一遍又一遍地调用自身),因此您正在创建无限递归。


属性(在 2.0 中)应该这样定义:

string _unescapedUrl; // <= private field

[DataMember]
public string unescapedUrl

    get  return _unescapedUrl;  
    set  _unescapedUrl = value; 

您有一个私有字段,然后在 getter 中返回该字段的值,并在 setter 中设置该字段的值。


顺便说一句,如果您使用的是 3.5 框架,则可以这样做并避免使用支持字段,并让编译器来处理:

public string unescapedUrl  get; set;

【讨论】:

据我所知,这台机器还没有更新到 3.5,所以我假设是 2.0。我已经尝试过 get/set 的事情,但它没有用,但那部分似乎工作得很好。 ...hmm,但如果我没记错的话,DataContractJsonSerializer 仅在 3.5 框架中可用,不是吗? 这很奇怪,因为 Visual Studio 在我的代码中识别 DataContractJsonSerializer 似乎没有问题,但它不喜欢使用 (get; set;)。 不管怎样,我已经将这台新机器升级到3.5,所以应该没有任何问题。 我添加了这行额外的代码,如果我尝试编写 g1.responseData.results,我会在屏幕上打印“results[]”,其他所有内容都打印为它们的名称(例如 g1 .responseData 打印“responseData”和 g1 打印“GoogleSearchResults”)。【参考方案2】:

您的数据类与 JSON 对象不匹配。改用这个:

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

此外,您不必实例化该类来获取其类型以进行反序列化:

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

【讨论】:

我刚刚尝试过,但我刚刚收到错误“找不到类型或命名空间名称 'IEnumerable'(您是否缺少 using 指令或程序集引用?)” . 没关系,我使用的是 System.Collections 而不是 System.Collection.Generic。它现在与该代码完美编译,但我需要做什么才能输出数据? 检查我更新的帖子,因为我发现您的代码中缺少什么【参考方案3】:

我发现了这种parse JSON into a dynamic object 的方法,它扩展了DynamicObjectjavascriptConverter 以将字符串转换为对象。

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

转换器

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

用法(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);

这个方法必须返回true,否则会抛出错误。例如。如果密钥不存在,则可以抛出错误。

返回true 并清空result 将返回一个空值,而不是引发错误。

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

【讨论】:

【参考方案4】:

我只是认为整个示例会很有用。这是这个问题的例子。

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; 

【讨论】:

【参考方案5】:

我尝试使用上面的代码,但没有成功。 Google 返回的 JSON 结构如此不同,辅助函数中有一个非常重要的遗漏:对 DataContractJsonSerializer.ReadObject() 的调用实际上将 JSON 数据反序列化为对象。

这是 2011 年 WORKS 的代码:

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; 
    

要获取第一个结果的内容,请执行以下操作:

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

【讨论】:

【参考方案6】:

感谢大家的帮助。 这是我的最终版本,感谢您的联合帮助! 我只展示我所做的更改,其余的都来自Joe Chung's 工作

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

        [DataMember]
        public string responseDetails  get; set; 

        [DataMember]
        public int responseStatus  get; set; 
    

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

【讨论】:

【参考方案7】:

Google Map API 请求并使用 C# 解析 DirectionsResponse,将 url 中的 json 更改为 xml 并使用以下代码将结果转换为可用的 C# 通用列表对象。

我花了一些时间来制作。但是这里是

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

我希望这会对某人有所帮助。

【讨论】:

以上是关于在 C# 中解析 JSON的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中解析 JSON

在 c# (Unity) 中解析 JSON 文件

如何在 C# 中解析复杂的 JSON?最终我想在 DataGridView 中显示结果 [关闭]

在 C# 中解析嵌套的复杂 JSON 响应

如何在统一 C# 中解析来自 JSON 的数据? [复制]

C#解析JSON实例