JavaScriptSerializer序列化和還原序列化JSON:使用自訂JavaScriptConverter

來源:互聯網
上載者:User

JSON的序列化和還原序列化已經成為Web開發必不可少的知識。現在常用的有System.Web.Script.Serialization下的JavaScriptSerializer來進行處理;另外一個比較常用且高效的類庫是JSON.NET。

在開發一些小的應用時,由於想盡量較少項目的依賴,所以不太願意使用JSON.NET。JavaScriptSerializer基本上能滿足簡單的需求,但當一個屬性要序列化成別的名字時,就顯得力不從心了。還有就是可能業務需要,某些屬性不希望在某一個條件下進行序列化。鑒於上面的業務需要,我們就需要自訂一個JavaScriptConverter。

自訂JavaScriptConverter的使用流程:

  • 定義一個JavaScriptConverter,指明期支援的類型。
  • 在序列化方法調用前註冊該轉換器。

顯然,這兩個步驟都不是很麻煩。我們舉一個具體的業務環境來說明:在ExtJS的TreePanel控制項中,TreeNode的屬性有id、text等,其中如果checked屬性存在,則屬性結果顯示節點選擇框。在C#中,checked是關鍵字,所以不能定義為屬性,TreeNode的C#代碼如下:

    public class TreeNode    {        public string id { get; set; }        public string text { get; set; }        public bool? isChecked { get; set; }        public List<TreeNode> children { get; set; }    }

我將checked屬性對應到類中的isChecked欄位,該欄位可以有三個狀態:null、true和false,當為null的時候,將不會序列化該欄位,前台也不會顯示節點選擇框。

現在要實現一個TreeNodeJSConverter,代碼如下:

    public class TreeNodeJSConverter : JavaScriptConverter    {        public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)        {            TreeNode node = new TreeNode();            object value = null;            if (dictionary.TryGetValue("id", out value))                node.id = (string)value;            if (dictionary.TryGetValue("text", out value))                node.text = (string)value;            if (dictionary.TryGetValue("children", out value))            {                if (value != null && value.GetType() == typeof(ArrayList))                {                    var list = (ArrayList)value;                    node.children = new List<TreeNode>();                    foreach (Dictionary<string, object> item in list)                    {                        node.children.Add((TreeNode)this.Deserialize(item, type, serializer));                    }                }                else                {                    node.children = null;                }            }            return node;        }        public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)        {            Dictionary<string, object> dic = new Dictionary<string, object>();            var node = obj as TreeNode;            if (node == null)                return null;            if(!string.IsNullOrEmpty(node.id))            dic.Add("id", node.id);            if (!string.IsNullOrEmpty(node.text))            dic.Add("text", node.text);            if (node.isChecked.HasValue)                dic.Add("checked", node.isChecked.Value);            if (node.children != null)            dic.Add("children", node.children);            return dic;        }        public override IEnumerable<Type> SupportedTypes        {            get            {                return new Type[] { typeof(TreeNode) };            }        }    }

代碼討論:TreeNodeJSConverter類首先需要繼承JavaScriptConverter,然後實現它的相關方法:Deserialize、Serialize和SupportedTypes,分別是還原序列化、序列化和支援的類型。

在序列化方法Serialize中,我們需要將屬性添加到一個字典結構中,就可以完成序列化的工作了。具體要序列化那些欄位還是要判斷一下相應的值是否存在。

在還原序列化方法Deserialize中,字典結構存放著相應的值,當值存在的時候就可以為TreeNode相應的欄位賦值。比較麻煩的事children屬性,因為其為嵌套的List類型,而JSON中的數組結構會被轉化成ArrayList結構,所以我們只需要遞迴的迴圈ArrayList中的每一個項,將其轉換為TreeNode就可以了。

最後是SupportedTypes欄位,返回支援的類型,我們這裡顯示的返回TreeNode的類型。

 

定義好了轉換器之後,我們需要為在序列化的時候註冊該轉換器即可:

        public static string SerializeToJson(object obj)        {            JavaScriptSerializer serializer = new JavaScriptSerializer();            serializer.RegisterConverters(new JavaScriptConverter[] { new TreeNodeJSConverter() });            return serializer.Serialize(obj);        }        public static T DeserializeJson<T>(string jsonString)        {            JavaScriptSerializer serializer = new JavaScriptSerializer();            serializer.RegisterConverters(new JavaScriptConverter[] { new TreeNodeJSConverter() });            return serializer.Deserialize<T>(jsonString);        }

代碼中標紅的部分就是註冊轉化器的地方,用起來很方便,代碼都貼出來了,不再提供源碼下載了。。親,早點睡吧!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.