JSON serialization and deserialization in .NET

近期常用到 AJAX 方式去呼叫後端的 Web Services,資料的傳遞交換均是用 JSON (JavaScript Object Notation),這篇主要是整理一些在 .NET 上序列化 (Serialization)和反序列化 (Deserialization)的小技巧和心得。
對於 JSON 的入門觀念可以參閱 Introducing JSON 或是 syshen's blog 中的 JSON 介紹。JSON 的資料格式簡言之可以看成是 Object 和 Array 的組合;Object 是指用大括號 {} 包起來的 string:value 的組合,如果多組組合的話,中間則是以逗號區隔,例如:{string1:value1, string2:value2, ....}。而 Array 的特徵則是用中括號 [] 包住以逗號區隔的 values。

接下來分別整理一下在 .NET 中對 JSON 做序列化和反序列化的動作。

序列化 (Serialization)
假設情境是,前端的 AJAX 對後端的 Web Service 做了一個呼叫,而我們想要回傳 JSON Data 的話,可以用下列的方式。
var query = from _table in DataContext
    .Table select _table; // obtain data by Linq 

System.Web.Script.Serialization.JavaScriptSerializer serializer 
    = new System.Web.Script.Serialization.JavaScriptSerializer();

List<Dictionary<string, object>> rows 
    = new List<Dictionary<string, object>>();

Dictionary<string, object> row;

foreach (var item in query) { 
    // each object can contains the number of string/value pairs 
    row = new Dictionary<string, object>();
    row.Add("string1", value1);
    row.Add("string2", value2);
}

return serializer.Serialize(rows);
反序列化 (Deserialization)
可能的情境是,後端的 Web Service 接收到前端的資料格式為 JSON 結構,可能是單筆也可能是多筆資料的集合;目前的話 .NET 3.5 以上可以用 DataContractJsonSerializer 類別來處理,或是可以用 Json.NET 做解析,使用上最大的差異在於 Json.NET 在做解析(parse)的時候並不需要事前建立對應的 Mapping-Table,但是 DataContractJsonSerializer 使用上必須對應到強型別的物件上 (strongly managed objects),所以需要事先宣告外,在資料結構上有異動時,還需要連動變更。

DataContractJsonSerializer Class
// before using DataContractJsonSerializer class
// , we need to claim the mapping data-types
[Serializable]
[DataContract]
public class DataObject
{

  [DataMember(Name = "title")]
  // can assign the custom property
  public string Title { get; set; }

  [DataMember(Name = "url")]
  public string URL { get; set; }
}


DataContractJsonSerializer ser 
    = new DataContractJsonSerializer(typeof(DataObject));

MemoryStream ms 
    = new MemoryStream(Encoding.Unicode.GetBytes(jsondata));

DataObject o = ser.ReadObject(ms) as DataObject;
但如果 JSON 內含有多筆的資料要如何處理呢? 例如:[{items:{"title": value, "url": value},{"title2": value, "url2": value}}]
// here we need defined List&lt;DataObject&gt;
[DataContract]
public class DataObjects
{
    [DataMember(Name = "items")]
    public List&lt;DataObject&gt; items { get; set; }
}

DataContractJsonSerializer ser 
    = new DataContractJsonSerializer(typeof(DataObjects));

MemoryStream ms 
    = new MemoryStream(Encoding.Unicode.GetBytes(jsondata));

DataObjects os = ser.ReadObject(ms) as DataObjects;


// loop data
foreach (DataObject o in os.items)
{
    Console.WriteLine(o.Title);
    Console.WriteLine(o.URL);
}
References:
Json.NET
如果是使用 Json.NET 的話,就不需要先宣告對應的型別,相對而言較彈性與簡潔;例如輸入的資料格式為:json = [{},{},{},.....,{}]
JArray a = JArray.Parse(json);
foreach (var item in a)
{
    JObject o = item as JObject;
    // Console.WriteLine((string)o["title"]);
}

Emily

許久沒有拿起相機了...謝謝鯰魚和 Eric 讓我也能一起去外拍插花 ^^

也謝謝 Emily 頂著大太陽跑了一整天,總是自然的對著鏡頭微笑

.....又詞窮了...總之,能心無旁騖的按著快門,真的是很快樂的一件事。

Street View@Google Map

小佛,你路邊停紅線被抓包了啦!
猛到讓我起雞皮疙瘩的服務...有人知道怎麼進這家公司嗎XD


檢視較大的地圖

My Lovely Son


終於和你見面了,抱著你,好溫暖,好幸福,更謝謝大家的關心與祝福,希望你能平安健康的長大,是我最深的心願。


murmur...眼睛有大很多,謝謝布丁的改良哈哈


我要睡覺啦,不要再拍了

2009 Ginat XTC HB3


July 17th, 2009
這台車的開箱文網路上已經一堆了,就不再贅述,補上他的出生照一張。


很久沒聽到 Whitney 的新歌了,昨晚回家的路上在警廣的節目中聽到這首歌,真的感動到眼淚都快流下來,雖然不是以前熟悉的高亢嗓音,但稍微的沙啞中感覺放了更多的感情,總之這是我很膚淺的敘述,但真的很推薦這首歌。

 
很喜歡這一句歌詞...
I crashed down and I tumbled, But I did not crumble.

Lyric / 中文版

(Verse 1)
Lost touch with my soul
I had nowhere to turn
I had nowhere to go
Lost sight of my dream
I thought it would be the end of me
I thought I'd never make it through
I had no hope to hold on to
I thought I would break

(Chorus)
I didn't know my own strength
I crashed down and I tumbled
But I did not crumble
I got through all the pain

I didn't know my own strength
Survived my darkest hour
My faith kept me alive
I picked myself back up
Hold my head up high
I was not built to break
I didn't know my own strength

(Verse 2)
Found hope in my heart
I found the light to light my way out of the dark
Found all that I need, here inside of me
I thought I'd never find my way
I thought that I'd never lift that weight
I thought I would break

(Chorus)
I didn't know my own strength
I crashed down and I tumbled
But I did not crumble
I got through all the pain

I didn't know my own strength
Survived my darkest hour
My faith kept me alive
I picked myself back up
Hold my head up high
I was not built to break
I didn't know my own strength

(Bridge)
There were so many times I
Wondered how I would get through the night I
Thought took all I could take

(Chorus)
I didn't know my own strength
I crashed down and I tumbled
But I did not crumble
I got through all the pain

I didn't know my own strength
Survived my darkest hour
My faith kept me alive
I picked myself back up
Hold my head up high
I was not built to break
I didn't know my own strength

(Outro)
I was not built to break
No no, I got to know my own strength

2009 綠


雨天後,總會在小徑旁找尋這樣的翠綠。
看著這些交錯的小草和圓滾滾的水珠...

總是讓我感受到滿滿的生命力!


沒有微距鏡,水珠上有樹的倒影喔。

依昀收涎


真佩服岳父大人,不知道去哪買到傳說中的收涎小餅乾,令人噴飯的是,接到岳父的電話時,我以為依昀的脖子是被一個圓圓的大餅乾圍繞,原來是用紅線哈哈,太妙了,這張雖然是模糊的,但是看她笑得超開心的啦哈哈,好可愛。


補上一張依昀的正妹定裝照,看她的小手還是緊緊握著餅乾,粉可愛捏哈哈

在網路上找「收涎」的民俗習慣解釋時,意外發現還可以這樣辦收涎趴,用 Mister Donut 當餅乾真的是很妙,等小明出來也要搞這種的,哈哈

轉眼間


轉眼間,五月到了...

懷著感恩與興奮的心情參加了口試,果然心臟要大顆一點才行..

這幾天隨手翻了「天使補習班1」,作者洗鍊的文字總令人感同身受。

很喜歡裡面的一段句子:

是我們的,要努力爭取,爭取不到的,鐵定不是我們的。

進研究室前,小穎熱心的喊了我來欣賞這美麗的光影2,糊的是我拍的。

喜歡這種似乎有柳暗花明又一村的光影。


這張清楚的應該才是小穎的神之手,哈哈。


再來糊一張,神秘詭譎的藍光。

murmur...亂七八糟的文字鋪陳..這篇有看懂得舉手哈哈,
跳 tone 跳很大 (純記錄)

1九歌文庫出版,游乾桂著,天使補習班
2攝於中研院資訊所新舊館交界

2009 天元宮春櫻

不知道從什麼時候開始,每年來天元宮拍櫻花的念頭總是隨著櫻花季的到來而越發濃烈..到也不是迷戀櫻花的美,只是這裡是那年的我們留下快樂回憶的地方...時間不停的前進著,兄弟們也朝著不同的方向努力著,只想告訴你們,很珍惜每次的相聚,因為總充滿著歡愉的氛圍。

PS.先解毒一下,雖然標題是天元宮的櫻花,但是這次沒有讓天元宮入景了,全部都是淺淺淺淺淺到爆的櫻花照哈哈

2009 阿里山 Sakura, Alishan, Taiwan

只有親自來到這裡,才能體驗她的美。

同場加映:
Island master B.H.E:阿里山 . 屬於我的記憶

這幾年每天走過的樹,從不曾仔細的觀察過,只覺得抽芽,新綠,花開,落葉這般的循環著..
這天照例上完網球課回研究室時,意識到樹下怎麼有一位大哥拿著相機猛拍,定睛一看才發現盛開的花束上滿滿的蝴蝶和蜜蜂忙碌著在採蜜,馬上衝回去拿了 GRD 來記錄這美麗的蝴蝶,這一位服務於 TEIA 的林大哥,很有學問,告訴我這種蝴蝶的學名是石牆蝶(Cyrestis thyodamas formosana),更不吝惜於分享他所知的知識,謝謝您林大哥!
最妙的是,可能中國人的好奇心真的太強了,尤其是看到一個人拿著相機在樹下不知道拍什麼,總計那天下午,我總共遇到了4團人,他們也是驚奇著樹上竟然掛了這麼多美麗的蝴蝶,石牆蝶的保護色不認真看還真的部會發現他的存在...
這棵樹在中研院資訊所舊館旁的停車場旁,除了有很乖的蝴蝶讓你拍個夠外,還認識了很多新朋友,蠻有趣的經驗,快來一起欣賞這些美麗的蝴蝶吧 ^o^

石牆蝶 Cyrestis thyodamas formosana

欽慧♥張寧婚宴紀錄


和張老師結緣是因為網球班和阿志的邀約,老師總是給人甜甜的溫暖感覺,氣質更是不需贅述,婚宴那天雖是第一天看到師丈,卻能感受到兩人的契合,學生衷心祝福老師您們幸福,快樂每一天。


這不是靈異照片啦,修圖的時候有看到張妹在角落偷笑,覺得還蠻妙的就留著了哈哈


和第一張不同的是,多了台下許多長輩的凝望與祝福。

本日我最正 — 亘亘


感謝 vivid 夫婦遠從台中北上探望狗頭兒夫婦,還帶了一位小天使,讓這幾天除了美食之外還有滿滿快樂的回憶 ^o^

[整理]如何顯示標題列於無資料的 GridView

如同 Kevin Marshall 所說的,使用 ASP.NET 中的 GridView 時,當你所繫結(binding)的來源是沒有資料的時候,GridView 會整個不見,也不會出現原本的 Header 或是 Footer,使用上非常的不便...以往便宜行事的作法先彈出一個 alert message,接著把 GridView 不顯示,實在是有點鳥...即便 GridView 裡面有 EmptyDataTemplate 可以先設定好沒有資料的時候要顯示何種資訊,但不能動態設定顯示和關閉...上述方式都有其缺陷。

歸納一下許多高手前輩的分享文,主要是透過繼承並擴展原有的 GridView 類別,新增相關控制的屬性(i.e. Header or Footer),接著覆寫(override) CreateChildControls Method 來建立對應輸出的表格。

以下是相關的文章:

  1. Kevin Marshall: Displaying GridView When No Data Exists
    根據發表日期和 Matt Berseth 在文中的引用說明,這一篇個人認為是原創文,裡面的概念寫的很清楚,很有參考價值。
  2. Matt Berseth: How To: Show Header and Footer Rows in an Empty GridView
    這篇文章中引用了 Kevin Marshall 的片段程式並加以改寫後,並且新增控制 Header 和 Footer 是否顯示的屬性。
  3. ASP.NET 魔法學院: 擴展 GridView 控制項 - 無資料時顯示標題列
    中文參考資料,以 VB.NET 撰寫。

其實看了上面的文章應該就能實做出來了,若還有需要可以參考以下的 Setp-by-Setp。

1. Add New Class.
首先新增一個類別,例如名為: EmptyGridView,接著你會發現 ASP.NET 中的 App_Code 資料夾裡面有一個 EmptyGridView.cs。

2. Set Namespace & Code.
接著為了引用的方便,我把 namespace 設定為 EmptyGridView,並設定該類別繼承自 GridView,最後貼上 Matt Berseth 文中的 code 即可。如以下所示:


namespace EmptyGridView
{
    public class EmptyGridView : GridView
    {
      // Copy Matt Berseth code here.
    }
}

3. Register the class.
接著在 ASP.NET 的頁面中,註冊這個 class。
<%@ Register TagPrefix="Custom" Namespace="EmptyGridView" %>

4. GridVew property.
最後在 GridView 中去設定相關的屬性(顯示/不顯示/文字)就可以了。最後在 Postback 的 Event 中,也能透過設定來動態控制。
<Custom:EmptyGridView ID="gv" runat="server" AutoGenerateColumns="false" ShowHeader="true" ShowHeaderWhenEmpty="true" EmptyDataText="沒有符合查詢條件的資料。">

最後是一些程式中不熟悉的地方的話,可以參考下列的文章:

資訊所舊館側門


平淡的構圖和鋪陳,但內心的感受是溫暖的。

2009 Happy Birthday!!


妳問我:開心嗎?
我說:這已經不是開心而已...是感動..

謝謝大家啦,我愛你們喔 ^_^

光陰的故事 — 憲光二村


好妙的樹幹!


缺了黃色的窗框...殘念


布丁和寶礦力


布丁? 梁文音?