CODE-使用JSON.NET處理動態物件屬性
| | | 1 | |
之前在文章裡提過.NET內建兩種JSON轉換工具: JavaScriptSerializer及DataContractJsonSerializer。不過,它們都基於一個假設--"JSON轉換對象是事先已知的Class"!
在某些狀況下,前端所傳回的JSON字串是開發階段無法完全掌握的。
舉個極端的例子。在Javascript裡可用以下寫法搞出一個你做夢都想不到的物件,轉成JSON傳到後端:
var o = {};
for (var i = 0; i < 10; i++)
o["Prop" + Math.floor(Math.random() * 100000)] = i;
var jsonString = JSON.stringify(o);
遇到這種機車需求,難道Server端就束手無策了嗎?
Thanks God, We have JSON.NET!! 一個極為出色的Open Source JSON解決方案,提供了如同JavaScriptSerializer序列化及反序列化JSON字串的功能,甚至支援LINQ式操作,最重要的是它可透過JObject的物件模型支援"動態物件",解決類別屬性不固定的問題。
以下是簡單的動態物件應用示範: (JSON.NET有親切易讀的說明文件,對Open Source Project來說十分難得,不可錯過了)
using System;using System.Linq;using Newtonsoft.Json;using Newtonsoft.Json.Linq;public partial class DynamicJson : System.Web.UI.Page
{public class Member
{public string Name;
public DateTime Birthday;public int Level;
public int[] Records;
}
protected void Page_Load(object sender, EventArgs e)
{ //使用傳統的強型別直接轉換 Member jeffrey = new Member() { Name = "Jeffrey", Birthday = new DateTime(1990, 1, 1),Level = 99,
Records = new int[] { 1024, 9999, 32767 }
};
//(哇塞! 我被序列化了)Response.Write(
JsonConvert.SerializeObject(jeffrey));
Response.Write("<hr />"); //動態產生Json的範例 JObject jo = new JObject();jo.Add(new JProperty("Name", "Jeffrey"));
jo.Add(new JProperty("Birthday", new DateTime(1990, 1, 1)));
jo.Add(new JProperty("Level", 99));
JArray ja = new JArray(); ja.Add(new JValue(1024)); ja.Add(new JValue(9999)); ja.Add(new JValue(32767));jo.Add(new JProperty("Records", ja));
Response.Write(JsonConvert.SerializeObject(jo));
Response.Write("<hr />"); //也可以像XDocument一樣一次宣告 jo = new JObject(new JProperty("Name", "Jeffrey"),
new JProperty("Birthday", new DateTime(1990, 1, 1)),
new JProperty("Level", 99),
new JProperty("Records",
new JArray(new JValue(1024), new JValue(9999),
new JValue(32767))
)
);
string jsonString = JsonConvert.SerializeObject(jo);Response.Write(jsonString);
Response.Write("<hr />");/* jsonString內容為{"Name":"Jeffrey","Birthday":"\/Date(631123200000+0800)\/","Level":99, "Records":[1024,9999,32767]} */ //JSON字串也可還原回JObject,動態存取JObject restoredObject = JsonConvert.DeserializeObject<JObject>(
jsonString);
//JObject可使用LINQ方式存取 var q = from p in restoredObject.Properties()where p.Name == "Name"
select p;
Response.Write("<li>Name = " + (string)q.First().Value);
Response.Write("<li>Birthday = " + (DateTime)jo.Property("Birthday").Value); int[] records = ((JArray)jo.Property("Records").Value) .Select(o => (int)o).ToArray();Response.Write("<li>Records = " + string.Join(",",
records.Select(o => o.ToString()).ToArray()));
/* * == 得到結果 == * Name = Jeffrey * Birthday = 1/1/1990 12:00:00 AM * Records = 1024,9999,32767 */Response.End();
}
}
Comments
# by 阿誠
幫助很多,感謝!