ASP.net 使用Json.Net第三方套件读取JSON字串
本文转自:http://www.dotblogs.com.tw/shadow/archive/2011/12/04/60576.aspx
Json.Net來读取JSON字串是因为此套件处理方式和之前待的Java Team中,使用的套件超像而且比起.net framework提供的类別,还可以序列/反序列化字典物件
Dictionary<string, int> original = new Dictionary<string, int>(); original.Add("A", 1); original.Add("B", 2); /*序列化Dictionary物件*/ string jsonStr = JsonConvert.SerializeObject(original,Formatting.Indented); /*Formatting.Indented,这样的字串输出在浏览器上显示的话有排版效果容易阅读*/ /*显示結果*/ Response.Write("Dictionary经过序列化:<br/>" + jsonStr + "<hr/>"); /*JSON字串反序列化为Dictionary*/ Dictionary<string, int> back = (Dictionary<string, int>)JsonConvert.DeserializeObject(jsonStr, typeof(Dictionary<string, int>)); foreach (string key in back.Keys) { Response.Write(key + "=>" + back[key] + "<br/>"); }
结果 (Dictionary被序列化后应该可以被当做JObject反序列化回來):

開始正文
要使用Json.NET的話,先到官網:http://json.codeplex.com/

下載紅框處
解壓縮後把Bin\Net資料夾底下的Newtonsoft.Json.dll放到Web Site專案的Bin目錄下即完成加入參考
要閱讀JSON字串的話,個人推薦Online JSON Viewer,
把JSON字串貼到Text頁籤的畫面上,可以再按Format排版

也可以再按Viewer進一步察看資料

如果JSON格式不符的話,會跳出一個alert訊息

算是輔助Debug的工具
(此篇文章只紀錄如何讀取JSON字串,至於怎麼產生JSON字串)
要讀取JSON字串中的資訊大概有幾種方法:
1.土方法,读取内容,针对键值分析使用 JObject、JArray、JProperty
2.Linq to Json
一開始先從簡單的JSON字串開始習慣吧
[ { "CategoryID": 1, "CategoryName": "飲料" }, { "CategoryID": 2, "CategoryName": "調味品" }, { "CategoryID": 3, "CategoryName": "點心" }, { "CategoryID": 4, "CategoryName": "日用品" }, { "CategoryID": 5, "CategoryName": "穀類/麥片" }, { "CategoryID": 6, "CategoryName": "肉/家禽" }, { "CategoryID": 7, "CategoryName": "特製品" }, { "CategoryID": 8, "CategoryName": "海鮮" }, { "CategoryID": 32, "CategoryName": "abc" } ]
這邊假設我要讀到CategoryID為6,它的CategoryName的值
1.土方法
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.UI; 6 using System.Web.UI.WebControls; 7 using System.Data; 8 using Newtonsoft.Json; 9 using System.Net; 10 using System.Web.Configuration; 11 using System.Text; 12 using Newtonsoft.Json.Linq; 13 14 public partial class ReadJson : System.Web.UI.Page 15 { 16 string WebSiteRoot = WebConfigurationManager.AppSettings["WebSiteRoot"]; 17 protected void Page_Load(object sender, EventArgs e) 18 { 19 20 WebClient wc = new WebClient(); 21 wc.Encoding = Encoding.UTF8; 22 /*載入JSON字串*/ 23 string jsonStr = wc.DownloadString(this.WebSiteRoot + "returnJSONStr.ashx"); 24 25 if (!IsPostBack)//Get Method 26 { 27 28 JArray array = JsonConvert.DeserializeObject<JArray>(jsonStr); 29 JObject obj = (JObject)array[5]; 30 /*注意key有分大小寫*/ 31 Response.Write(obj.Value<string>("CategoryName"));/*取得該CategoryName的值*/ 32 Response.Write("<br/>"); 33 Response.Write(obj.Property("CategoryName").Value);/*這樣也可以*/ 34 Response.Write("<br />"); 35 Response.Write(obj["CategoryName"]);/*更精簡的寫法*/ 36 Response.Write("<br />"); 37 /*或這樣跑迴圈↓*/ 38 foreach (JObject Jobj in array) 39 { 40 if (Jobj["CategoryID"].ToString() == "6") 41 { 42 Response.Write(Jobj["CategoryName"].ToString()); 43 } 44 } 45 } 46 } 47 48 }
執行結果:

2.使用Linq to Json
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.UI; 6 using System.Web.UI.WebControls; 7 using System.Data; 8 using Newtonsoft.Json; 9 using System.Net; 10 using System.Web.Configuration; 11 using System.Text; 12 using Newtonsoft.Json.Linq; 13 14 public partial class ReadJson : System.Web.UI.Page 15 { 16 string WebSiteRoot = WebConfigurationManager.AppSettings["WebSiteRoot"]; 17 protected void Page_Load(object sender, EventArgs e) 18 { 19 20 WebClient wc = new WebClient(); 21 wc.Encoding = Encoding.UTF8; 22 /*載入JSON字串*/ 23 string jsonStr = wc.DownloadString(this.WebSiteRoot + "returnJSONStr.ashx"); 24 25 if (!IsPostBack)//Get Method 26 { 27 JArray array = JsonConvert.DeserializeObject<JArray>(jsonStr); 28 var result = from objs in array.Values<JObject>() /*走訪JArray裡每一筆JObject*/ 29 where objs["CategoryID"].ToString()=="6" 30 select objs; 31 32 /*只取一筆的值*/ 33 Response.Write(result.Single<JObject>()["CategoryName"].ToString()); 34 } 35 } 36 37 38 39 }
執行結果:

要讀取JSON字串中的某個訊息最好習慣跑迴圈的方式,這樣寫開發速度會較快
因為以上JSON字串剛好是DataTable轉出來的,所以使用Linq to Json感覺會像平常Linq to SQL一樣
習慣之後來找複雜一點的範例當練習

這次就來判斷如果此份資料的status為OK的話
就找出results裡formatted_address的地址資訊和geometry裡location的lat和lng的值
還有geometry裡locatioon_type的值
以下為JsonViewer排過的版

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.UI; 6 using System.Web.UI.WebControls; 7 using System.Data; 8 using Newtonsoft.Json; 9 using System.Net; 10 using System.Web.Configuration; 11 using System.Text; 12 using Newtonsoft.Json.Linq; 13 using System.IO; 14 15 public partial class ReadJson : System.Web.UI.Page 16 { 17 string WebSiteRoot = WebConfigurationManager.AppSettings["WebSiteRoot"]; 18 protected void Page_Load(object sender, EventArgs e) 19 { 20 21 FileStream fs = new FileStream(Server.MapPath("~/JsonText.txt"), FileMode.Open); 22 StreamReader sr = new StreamReader(fs); 23 /*載入JSON字串*/ 24 string jsonStr = sr.ReadToEnd(); 25 sr.Close(); 26 fs.Close(); 27 28 if (!IsPostBack)//Get Method 29 { 30 JObject obj = JsonConvert.DeserializeObject<JObject>(jsonStr); 31 32 if (obj["status"].ToString()=="OK") 33 { 34 JArray array = (JArray)obj["results"]; 35 foreach (JObject obj_results in array)/*走訪JArray(results裡的每一筆JObject(這裡只有一筆)*/ 36 { 37 Response.Write("formatted_address的值為:" + obj_results["formatted_address"].ToString() + "<br/>"); 38 39 Response.Write("location的lat為:" +obj_results["geometry"]["location"]["lat"].ToString()+"<br/>"); 40 Response.Write("location的lng為:" +obj_results["geometry"]["location"]["lng"].ToString()+"<br/>"); 41 42 Response.Write("geometry的location_type為:" + obj_results["geometry"]["location_type"].ToString()); 43 44 45 } 46 47 48 } 49 50 } 51 } 52 53 54 55 }
執行結果:

使用Linq to Json
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.UI; 6 using System.Web.UI.WebControls; 7 using System.Data; 8 using Newtonsoft.Json; 9 using System.Net; 10 using System.Web.Configuration; 11 using System.Text; 12 using Newtonsoft.Json.Linq; 13 using System.IO; 14 15 public partial class ReadJson : System.Web.UI.Page 16 { 17 string WebSiteRoot = WebConfigurationManager.AppSettings["WebSiteRoot"]; 18 protected void Page_Load(object sender, EventArgs e) 19 { 20 21 FileStream fs = new FileStream(Server.MapPath("~/JsonText.txt"), FileMode.Open); 22 StreamReader sr = new StreamReader(fs); 23 /*載入JSON字串*/ 24 string jsonStr = sr.ReadToEnd(); 25 sr.Close(); 26 fs.Close(); 27 28 if (!IsPostBack)//Get Method 29 { 30 JObject obj = JsonConvert.DeserializeObject<JObject>(jsonStr); 31 32 if (obj["status"].ToString()=="OK") 33 { 34 JArray array = (JArray)obj["results"]; 35 36 37 //抓出JArray裡的一筆JObject的所有JProperty 38 var result = from Orz in array.Values<JObject>().Single<JObject>().Properties() 39 where Orz.Name == "formatted_address" || Orz.Name == "geometry" 40 select Orz; 41 42 foreach (JProperty item in result) 43 { 44 if (item.Name=="formatted_address") 45 {//直接顯示Value 46 Response.Write("formatted_address的值為:" + item.Value.ToString() + "<br/>"); 47 } 48 else 49 {//JProperty的Name為geometry 50 //geometry內含location和location_type兩個鍵值 51 //item.Value["location"]會返回一個JObject 52 Response.Write("location的lat為:" + item.Value["location"]["lat"].ToString() + "<br/>"); 53 Response.Write("location的lng為:" + item.Value["location"]["lng"].ToString() + "<br/>"); 54 //item.Value["location_type"]會返回一個字串 55 Response.Write("geometry的location_type為:" + item.Value["location_type"]); 56 57 } 58 } 59 60 61 62 } 63 64 } 65 } 66 67 68 69 }
執行結果:

總而言之,要取值(JValue)的方式
JObject:使用obj["鍵"].ToString()
JProperty:使用prj.Value["鍵"].ToString()
JArray:跑迴圈找JObject或指定索引 array[index]
DateTime型別的存取
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.UI; 6 using System.Web.UI.WebControls; 7 /*Json.NET相關的命名空間*/ 8 using Newtonsoft.Json.Linq; 9 using Newtonsoft.Json; 10 11 public partial class _Default : System.Web.UI.Page 12 { 13 protected void Page_Load(object sender, EventArgs e) 14 { 15 if (!IsPostBack)//Get Method 16 { 17 18 JObject obj = new JObject(); 19 obj.Add("now", DateTime.Now); 20 string json = JsonConvert.SerializeObject(obj);/*序列化*/ 21 Response.Write("一個JObject物件=>"+json+"<hr/>"); 22 23 24 JObject obj_back = JsonConvert.DeserializeObject<JObject>(json);/*反序列化*/ 25 Response.Write("將JSON字串轉回JObject物件再取出now的JValue=>" + obj_back["now"] + "<hr/>"); 26 obj_back = JObject.Parse(json);/*也可以這樣將JSON字串轉回JObject*/ 27 Response.Write("將JSON字串轉回JObject物件再取出now的JValue=>" + obj_back["now"] + "<hr/>"); 28 DateTime myDT = Convert.ToDateTime(obj_back["now"].ToString()); 29 Response.Write("再轉成DateTime物件=>"+myDT.ToString()); 30 31 } 32 } 33 }
執行結果:

如果要讀取的Json字串結構很複雜很巢狀的話
這裡再提供一個利用IDE工具intellisense的「物件存取」方法:
同樣以Google API的這篇最後一組字串當範例:
1. 先把Json字串全部複製

接著定義類別,類別不用自己寫,用線上工具產生即可
到json2csharp把剛剛複製的Json字串貼上,按下Generate鈕

3. Visual Studio新增一個類別檔.cs
把剛剛複製的類別字串貼上即可

4.再來寫程式把Json字串讀進來再用JsonConvert.DeserializeObject反序列化為RootObject物件就可以存取了

再给大家介绍一个自动生成JSON的实体类工具
一个复杂的实体类,我们自己去写的话,可能需要1个小时以上。 那有没有工具能直接生成实体类呢,这样能方便太多了。 当然有http://jsonclassgenerator.codeplex.com/ ----开源的winform工具

Json.NET官方說明文件:http://james.newtonking.com/projects/json/help/
衍伸閱讀文章:[ASP.net WebForm] 利用JSON.net 實現 DataTable轉JSON字串、JSON字串轉DataTable
[C#]Json.NET - A high performance Json library
LINQ to JSON 官方API

浙公网安备 33010602011771号