[ASP.net WebForm] 使用Json.Net第三方套件讀取JSON字串
(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字串,改天有空再寫:2012.8.16補上[C#.net] 產生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["鍵"].ToString()
JProperty:使用prj.Value["鍵"].ToString()
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());
}
}
}
執行結果:
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