(JSON的基礎簡介請看這:ASP.NET中JSON的序列化和反序列化)
會選擇Json.Net來讀取JSON字串是因為此套件處理方式和之前待的Java Team中,使用的套件超像
而且比起.net framework提供的類別,還可以序列/反序列化字典物件
Dictionary< string , int > original = new Dictionary< string , int >(); |
string jsonStr = JsonConvert.SerializeObject(original,Formatting.Indented); |
Response.Write( "Dictionary物件經過序列化:<br/>" + jsonStr + "<hr/>" ); |
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字串,改天有空再寫:2012.8.16補上[C#.net] 產生JSON字串的幾種方式整理)
要讀取JSON字串中的資訊大概有幾種方法:
1.屠髮練肛土法鍊鋼法:使用JObject、JArray、JProperty的成員一直讀到自己想要的資訊(JValue)
2.Linq to Json
一開始先從簡單的JSON字串開始習慣吧
這邊假設我要讀到CategoryID為6,它的CategoryName的值
1.土法鍊鋼法:
using System.Collections.Generic; |
using System.Web.UI.WebControls; |
using System.Web.Configuration; |
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; |
string jsonStr = wc.DownloadString( this .WebSiteRoot + "returnJSONStr.ashx" ); |
JArray array = JsonConvert.DeserializeObject<JArray>(jsonStr); |
JObject obj = (JObject)array[5]; |
Response.Write(obj.Value< string >( "CategoryName" )); |
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.Collections.Generic; |
using System.Web.UI.WebControls; |
using System.Web.Configuration; |
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; |
string jsonStr = wc.DownloadString( this .WebSiteRoot + "returnJSONStr.ashx" ); |
JArray array = JsonConvert.DeserializeObject<JArray>(jsonStr); |
var result = from objs in array.Values<JObject>() |
where objs[ "CategoryID" ].ToString()== "6" |
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.Collections.Generic; |
using System.Web.UI.WebControls; |
using System.Web.Configuration; |
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) |
FileStream fs = new FileStream(Server.MapPath( "~/JsonText.txt" ), FileMode.Open); |
StreamReader sr = new StreamReader(fs); |
string jsonStr = sr.ReadToEnd(); |
JObject obj = JsonConvert.DeserializeObject<JObject>(jsonStr); |
if (obj[ "status" ].ToString()== "OK" ) |
JArray array = (JArray)obj[ "results" ]; |
foreach (JObject obj_results in array) |
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.Collections.Generic; |
using System.Web.UI.WebControls; |
using System.Web.Configuration; |
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) |
FileStream fs = new FileStream(Server.MapPath( "~/JsonText.txt" ), FileMode.Open); |
StreamReader sr = new StreamReader(fs); |
string jsonStr = sr.ReadToEnd(); |
JObject obj = JsonConvert.DeserializeObject<JObject>(jsonStr); |
if (obj[ "status" ].ToString()== "OK" ) |
JArray array = (JArray)obj[ "results" ]; |
var result = from Orz in array.Values<JObject>().Single<JObject>().Properties() |
where Orz.Name == "formatted_address" || Orz.Name == "geometry" |
foreach (JProperty item in result) |
if (item.Name== "formatted_address" ) |
Response.Write( "formatted_address的值為:" + item.Value.ToString() + "<br/>" ); |
Response.Write( "location的lat為:" + item.Value[ "location" ][ "lat" ].ToString() + "<br/>" ); |
Response.Write( "location的lng為:" + item.Value[ "location" ][ "lng" ].ToString() + "<br/>" ); |
Response.Write( "geometry的location_type為:" + item.Value[ "location_type" ]); |
執行結果:
總而言之,要取值(JValue)的方式
JObject:使用obj["鍵"].ToString()
JProperty:使用prj.Value["鍵"].ToString()
JArray:跑迴圈找JObject或指定索引 array[index]
2011.12.04 追記
DateTime型別的存取
using System.Collections.Generic; |
using System.Web.UI.WebControls; |
using Newtonsoft.Json.Linq; |
public partial class _Default : System.Web.UI.Page |
protected void Page_Load( object sender, EventArgs e) |
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); |
Response.Write( "將JSON字串轉回JObject物件再取出now的JValue=>" + obj_back[ "now" ] + "<hr/>" ); |
DateTime myDT = Convert.ToDateTime(obj_back[ "now" ].ToString()); |
Response.Write( "再轉成DateTime物件=>" +myDT.ToString()); |
執行結果:
2012.8.16 追記
如果要讀取的Json字串結構很複雜很巢狀的話
這裡再提供一個利用IDE工具intellisense的「物件存取」方法:
同樣以Google API的這篇最後一組字串當範例:
1. 先把Json字串全部複製
2. 接著定義類別,類別不用自己寫,用線上工具產生即可
到json2csharp把剛剛複製的Json字串貼上,按下Generate鈕
3. Visual Studio新增一個類別檔.cs
把剛剛複製的類別字串貼上即可
4.再來寫程式把Json字串讀進來再用JsonConvert.DeserializeObject反序列化為RootObject物件就可以存取了
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