2012年5月17日 星期四

Metro App 下使用 Json.Net 的取代方案…

從開始在 Windows Phone 的專案上處理 Json 資料時就一直使用 Json.Net
使用上都沒遇到什麼問題…效率方面也很好…
但最近在寫 Windows 8 Metro Style App 時卻發生一件詭異的事…

這件詭異的事和 Windows Phone 的 Unsupported APIs 有點類似…
大致上就是使用了某些 API 在實體機器、模擬器上執行都沒問題…
卻在上架時發生靜態分析被提示 api unsupported 必須拿掉指令的狀況…
我個人是覺得有點整人…畢竟不是每天在看 MSDN 所以知道這類資訊…
應該在 compiler、runtime 時就告知會來得更好才是…

這次 Download 了 Json.Net 支援 Windows RT 的 5/8 最新版下來用…
同樣在 Windows 8 的機器、模擬器上皆正常執行…
卻在跑分析時被提示 Newtonsoft.Json.dll 中有數個指令不合法…
如果這問題不處理當然是無法繼續上架的流程…

一直以來對 C# Json 官方 SDK 印像一直停留在 DataContractJsonSerializer
但是這個和利用 Json.Net 處理資料的方式相差太大了…改起來要人命…
查詢之下發現在 .Net 4.5 後有一個 System.Json 可以用…
這在處理 Json 資料的方式上和 Json.Net 非常相似…
比較需要注意的是 Windows Runtime 上的 namespace 為 Windows.Data.Json
另外一點就是它對於型別的檢查比 Json.Net 嚴格許多…
如果 JsonValue 為數字…卻使用 GetString Method 會造成 Exception…

假設我們要解析以下結構…

{
id: 0,
title: "Hello",
list: [
{
id: 1,
name: "aaa"
},
{
id: 2,
name: "bbb"
},
{
id: 3,
name: "ccc"
}]
}

簡單常用的範例如下…

using Windows.Data.Json;


// Json.Net - 取得 Json 物件
JObject jsonObj = JObject.Parse(strJsonText);

// C# Json Parser - 取得 Json 物件
JsonObject jsonObj = JsonObject.Parse(strJsonText);

--------------------------------------------------------

// Json.Net - 取得字串
String strTitle = jsonObj["title"].ToString();

// C# Json Parser - 取得字串
String strTitle = jsonObj["title"].GetString();

--------------------------------------------------------

// Json.Net - 取得數字
int id = int.Parse(jsonObj["id"].ToString());

// C# Json Parser - 取得數字
int id = jsonObj["id"].GetNumber();

--------------------------------------------------------

// Json.Net - 解析陣列
JToken jList = jsonObj["list"];
if(jList != null && jList.HasValue)
{
JToken jItem = jList.First;
while (jItem != null && jItem.HasValue)
{
int itemId = int.Parse(jItem["id"].ToString());
String itemName = jItem["name"].ToString();
jItem = jItem.Next;
}
}

// C# Json Parser - 解析陣列
JsonArray jList = jsonObj["list"].GetArray();
if(jList != null && jList.Count > 0)
{
for(int i = 0; i < jList.Count; ++i)
{
JsonObject jItem = jList.GetObjectAt(i);
int itemId = jItem["id"].GetNumber();
String itemName = jItem["name"].GetString();
}
}


沒有留言:

張貼留言