Google Code Prettify

產生JSON字串的幾種方式整理(2)

4. 物件序列化
這個要先知道輸出的json字串長什麼樣子
貼到http://json2csharp.com/去產生類別程式碼
image
然後

01protected void Page_Load(object sender, EventArgs e)
02{
03    if (!IsPostBack)//Get Method
04    {
05        //準備資料
06        string collapse_key = "score_update";
07        int time_to_live = 108;
08        bool delay_while_idle = true;
09        string score = "4x8";
10        string time = "15:16.2342";
11        List<string> registration_ids = new List<string>() { "4","8","15","16","23","42"};
12 
13          
14        //建立物件,塞資料
15        RootObject root = new RootObject();
16        root.collapse_key = collapse_key;
17        root.time_to_live = time_to_live;
18        root.delay_while_idle = delay_while_idle;
19        Data data = new Data();
20        root.data = data;
21        root.data.score = score;
22        root.data.time = time;
23        root.registration_ids = registration_ids;
24        //物件序列化
25        string strJson = JsonConvert.SerializeObject(root, Formatting.Indented);
26        //輸出結果
27        Response.Write(strJson);
28    }
29}
或使用物件初始化方式塞值
01protected void Page_Load(object sender, EventArgs e)
02{
03    if (!IsPostBack)//Get Method
04    {
05        //準備資料
06        string collapse_key = "score_update";
07        int time_to_live = 108;
08        bool delay_while_idle = true;
09        string score = "4x8";
10        string time = "15:16.2342";
11        List<string> registration_ids = new List<string>() { "4","8","15","16","23","42"};
12 
13          
14        //建立物件,塞資料
15        RootObject root = new RootObject()
16        {
17            collapse_key = collapse_key,
18            time_to_live = time_to_live,
19            delay_while_idle = delay_while_idle,
20            data = new Data()
21            {
22               score = score,
23               time=time
24            },
25            registration_ids = registration_ids
26        };
27         
28        //物件序列化
29        string strJson = JsonConvert.SerializeObject(root, Formatting.Indented);
30        //輸出結果
31        Response.Write(strJson);
32    }
33}
使用物件初始化方式塞值看起來直覺多了
不過為了物件序列化還要特地宣告類別,這…倒不如使用Linq吧

5.用Linq+匿名物件寫法 直接組JSON
這招在Json.net的官方文件有範例(用JObject.FromObject的那個):http://james.newtonking.com/projects/json/help/html/CreatingLINQtoJSON.htm
但只有範例,沒寫為什麼Linq要那樣寫,誰看得懂阿XD
要用Linq直接組JSON
大概把握幾點:
Json Object:Json字串用大括號{}表示,Linq也是用大括號{}表示
Json Object的Name(Key、Property):Json字串在兩個雙引號””裡寫一個英文單字,Linq就直接寫英文單字即可
Json Array:Json字串用中括號[]表示,Linq就用from o in XXX select o,這種回傳IEnumerable的寫法(如果JSON字串是物件陣列的話就用from o in XXX select new {欄位1=YYY}這種形式)
Json Value:Linq就看Json字串填什麼值就跟著填什麼值
01protected void Page_Load(object sender, EventArgs e)
02{
03    if (!IsPostBack)//Get Method
04    {
05        //準備資料
06        List<string> registration_ids = new List<string>() { "4""8""15""16""23""42" };
07 
08        //用Linq直接組
09        var result = new
10                        {
11                            collapse_key = "score_update",
12                            time_to_live = 108,
13                            delay_while_idle = true,
14                            data = new{
15                                score ="4x8",
16                                time = "15:16.2342"
17                            },
18                            registration_ids = from s in registration_ids
19                                                        select s
20 
21                        };
22 
23        //序列化為JSON字串並輸出結果
24        Response.Write(JsonConvert.SerializeObject(result));
25    }
26}
請看圖示解說↓
image
由於Linq支援DataTable的查詢,所以再難的JSON格式都組得出來,不用再跑for迴圈寫一堆Code,開發速度大幅提昇
以下截自實務上的一段Code(有做了一點修改)
01DataTable dt = new DataTable();//撈出一張資料表的所有數據(這個表類似北風資料庫的員工資料表,有階層關係)
02DataTable dtDetail = new DataTable();//上一張表的一對多明細表
03var firstLevel = dt.Select("pid is NULL");//第一層數據
04var result = new
05{
06      Info = new
07    {
08        Level1 = from a in firstLevel
09                 join b in dt.AsEnumerable() on a.Field<int>("id") equals b.Field<int?>("pid") into secondLevel
10                 select new
11                 {
12                     Title =  a.Field<string>("Title"),
13                     Level2 = secondLevel.Select(c => new
14                     {
15                         Title =  c.Field<string>("Title"),
16                         Photos = from s in secondLevel
17                                       join uu in dtDetail.AsEnumerable() on s.Field<int>("id") equals uu.Field<int>("id")
18                                       where s.Field<int>("id") == c.Field<int>("id")
19                                select new
20                                {
21                                    PhotoID = uu.Field<string>("PhotoID"),
22                                    PhotoTitle = uu.Field<string>("PhotoTitle")
23                                }
24 
25                     })
26                 }
27    }
28};
※不過要注意對於寫的人是寫很快,後人維護會有閱讀困難的可能


最後附上一張比較圖
image