出處:http://www.dotblogs.com.tw/shadow/archive/2011/12/04/60576.aspx
(JSON的基礎簡介請看這:ASP.NET中JSON的序列化和反序列化)
會選擇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的成員一直讀到自己想要的資訊(JValue)
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.土法鍊鋼法:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data; using Newtonsoft.Json; using System.Net; using System.Web.Configuration; using System.Text; using Newtonsoft.Json.Linq; public partial class ReadJson : System.Web.UI.Page { string WebSiteRoot = WebConfigurationManager.AppSettings["WebSiteRoot"]; protected void Page_Load(object sender, EventArgs e) { WebClient wc = new WebClient(); wc.Encoding = Encoding.UTF8; /*載入JSON字串*/ string jsonStr = wc.DownloadString(this.WebSiteRoot + "returnJSONStr.ashx"); if (!IsPostBack)//Get Method { JArray array = JsonConvert.DeserializeObject<JArray>(jsonStr); JObject obj = (JObject)array[5]; /*注意key有分大小寫*/ Response.Write(obj.Value<string>("CategoryName"));/*取得該CategoryName的值*/ Response.Write("<br/>"); Response.Write(obj.Property("CategoryName").Value);/*這樣也可以*/ Response.Write("<br />"); Response.Write(obj["CategoryName"]);/*更精簡的寫法*/ Response.Write("<br />"); /*或這樣跑迴圈↓*/ foreach (JObject Jobj in array) { if (Jobj["CategoryID"].ToString() == "6") { Response.Write(Jobj["CategoryName"].ToString()); } } } } }
執行結果:
[檢視圖片]
2.使用Linq to Json
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data; using Newtonsoft.Json; using System.Net; using System.Web.Configuration; using System.Text; using Newtonsoft.Json.Linq; public partial class ReadJson : System.Web.UI.Page { string WebSiteRoot = WebConfigurationManager.AppSettings["WebSiteRoot"]; protected void Page_Load(object sender, EventArgs e) { WebClient wc = new WebClient(); wc.Encoding = Encoding.UTF8; /*載入JSON字串*/ string jsonStr = wc.DownloadString(this.WebSiteRoot + "returnJSONStr.ashx"); if (!IsPostBack)//Get Method { JArray array = JsonConvert.DeserializeObject<JArray>(jsonStr); var result = from objs in array.Values<JObject>() /*走訪JArray裡每一筆JObject*/ where objs["CategoryID"].ToString()=="6" select objs; /*只取一筆的值*/ Response.Write(result.Single<JObject>()["CategoryName"].ToString()); } } }
執行結果:
[檢視圖片]
要讀取JSON字串中的某個訊息最好習慣跑迴圈的方式,這樣寫開發速度會較快
因為以上JSON字串剛好是DataTable轉出來的,所以使用Linq to Json感覺會像平常Linq to SQL一樣
習慣之後來找複雜一點的範例當練習
[檢視圖片]
這次就來判斷如果此份資料的status為OK的話
就找出results裡formatted_address的地址資訊和geometry裡location的lat和lng的值
還有geometry裡locatioon_type的值
以下為JsonViewer排過的版
[檢視圖片]
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data; using Newtonsoft.Json; using System.Net; using System.Web.Configuration; using System.Text; using Newtonsoft.Json.Linq; using System.IO; public partial class ReadJson : System.Web.UI.Page { string WebSiteRoot = WebConfigurationManager.AppSettings["WebSiteRoot"]; protected void Page_Load(object sender, EventArgs e) { FileStream fs = new FileStream(Server.MapPath("~/JsonText.txt"), FileMode.Open); StreamReader sr = new StreamReader(fs); /*載入JSON字串*/ string jsonStr = sr.ReadToEnd(); sr.Close(); fs.Close(); if (!IsPostBack)//Get Method { JObject obj = JsonConvert.DeserializeObject<JObject>(jsonStr); if (obj["status"].ToString()=="OK") { JArray array = (JArray)obj["results"]; foreach (JObject obj_results in array)/*走訪JArray(results裡的每一筆JObject(這裡只有一筆)*/ { Response.Write("formatted_address的值為:" + obj_results["formatted_address"].ToString() + "<br/>"); Response.Write("location的lat為:" +obj_results["geometry"]["location"]["lat"].ToString()+"<br/>"); Response.Write("location的lng為:" +obj_results["geometry"]["location"]["lng"].ToString()+"<br/>"); Response.Write("geometry的location_type為:" + obj_results["geometry"]["location_type"].ToString()); } } } } }
執行結果:
[檢視圖片]
使用Linq to Json
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data; using Newtonsoft.Json; using System.Net; using System.Web.Configuration; using System.Text; using Newtonsoft.Json.Linq; using System.IO; public partial class ReadJson : System.Web.UI.Page { string WebSiteRoot = WebConfigurationManager.AppSettings["WebSiteRoot"]; protected void Page_Load(object sender, EventArgs e) { FileStream fs = new FileStream(Server.MapPath("~/JsonText.txt"), FileMode.Open); StreamReader sr = new StreamReader(fs); /*載入JSON字串*/ string jsonStr = sr.ReadToEnd(); sr.Close(); fs.Close(); if (!IsPostBack)//Get Method { JObject obj = JsonConvert.DeserializeObject<JObject>(jsonStr); if (obj["status"].ToString()=="OK") { JArray array = (JArray)obj["results"]; //抓出JArray裡的一筆JObject的所有JProperty var result = from Orz in array.Values<JObject>().Single<JObject>().Properties() where Orz.Name == "formatted_address" || Orz.Name == "geometry" select Orz; foreach (JProperty item in result) { if (item.Name=="formatted_address") {//直接顯示Value Response.Write("formatted_address的值為:" + item.Value.ToString() + "<br/>"); } else {//JProperty的Name為geometry //geometry內含location和location_type兩個鍵值 //item.Value["location"]會返回一個JObject Response.Write("location的lat為:" + item.Value["location"]["lat"].ToString() + "<br/>"); Response.Write("location的lng為:" + item.Value["location"]["lng"].ToString() + "<br/>"); //item.Value["location_type"]會返回一個字串 Response.Write("geometry的location_type為:" + item.Value["location_type"]); } } } } } }
執行結果:
[檢視圖片]
總而言之,要取值(JValue)的方式
JObject:使用obj["鍵"]
JProperty:使用prj.Value["鍵"]
JArray:跑迴圈找JObject或指定索引 array[index]
2011.12.04 追記
DateTime型別的存取
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; /*Json.NET相關的命名空間*/ using Newtonsoft.Json.Linq; using Newtonsoft.Json; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack)//Get Method { JObject obj = new JObject(); obj.Add("now", DateTime.Now); string json = JsonConvert.SerializeObject(obj);/*序列化*/ Response.Write("一個JObject物件=>"+json+"<hr/>"); JObject obj_back = JsonConvert.DeserializeObject<JObject>(json);/*反序列化*/ Response.Write("將JSON字串轉回JObject物件再取出now的JValue=>" + obj_back["now"] + "<hr/>"); obj_back = JObject.Parse(json);/*也可以這樣將JSON字串轉回JObject*/ Response.Write("將JSON字串轉回JObject物件再取出now的JValue=>" + obj_back["now"] + "<hr/>"); DateTime myDT = Convert.ToDateTime(obj_back["now"].ToString()); Response.Write("再轉成DateTime物件=>"+myDT.ToString()); } } }
執行結果:
[檢視圖片]
Json.NET官方說明文件:http://james.newtonking.com/projects/json/help/