JavaScriptSerializer序列化和反序列化JSON:使用自定义JavaScriptConverter

简介:

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);
        }


本文转自齐师傅博客园博客,原文链接:http://www.cnblogs.com/youring2/archive/2013/01/10/Custom_JavaScriptConverter.html,如需转载请自行联系原作者
相关文章
|
JavaScript 前端开发 Shell
NPM 自定义 package.json 中 scripts 命令(& 与 && 的区别,cross-env 的使用)
NPM 自定义 package.json 中 scripts 命令(& 与 && 的区别,cross-env 的使用)
292 0
|
6月前
|
编解码 JavaScript 前端开发
TypeScript【第三方声明文件、自定义声明文件、tsconfig.json文件简介、tsconfig.json 文件结构与配置】(六)-全面详解(学习总结---从入门到深化)
TypeScript【第三方声明文件、自定义声明文件、tsconfig.json文件简介、tsconfig.json 文件结构与配置】(六)-全面详解(学习总结---从入门到深化)
321 0
|
6月前
|
JavaScript 前端开发 Shell
NPM 自定义 package.json 中 scripts 命令(& 与 && 的区别,cross-env 的使用)
NPM 自定义 package.json 中 scripts 命令(& 与 && 的区别,cross-env 的使用)
228 0
|
6月前
|
JSON JavaScript 前端开发
vue的 blob文件下载文件时,后端自定义异常,并返回json错误提示信息,前端捕获信息并展示给用户
vue的 blob文件下载文件时,后端自定义异常,并返回json错误提示信息,前端捕获信息并展示给用户
|
6月前
|
JSON 数据格式
gson自定义Type解析json数组字符串
gson自定义Type解析json数组字符串
|
JSON JavaScript 数据处理
vue+element 返回数组或json数据自定义某列显示的处理--两种方法
本文是作者开发一个业务需求时,将返回数据列表的其中一个数据长度很长的字段处理成数组,并将其作为子表显示的过程,具体样式如下(数据做了马赛克处理) ![请在此添加图片描述](https://developer-private-1258344699.cos.ap-guangzhou.myqcloud.com/column/article/5877188/20231030-902560ce.png?x-cos-security-token=v61lCvRHgTvmeijokvUBGGxbT01lDU8ac78083fc31c5e3a734833edd862768549WL7GvROHQNGkc9F
147 0
vue+element 返回数组或json数据自定义某列显示的处理--两种方法
|
JSON 前端开发 Java
springboot中自定义JavaBean返回的json对象属性名称大写变小写问题
springboot中自定义JavaBean返回的json对象属性名称大写变小写问题
201 0
|
前端开发 JavaScript 程序员
CommonJs自定义模块的使用/npm 包 第三方模块/package.json版本信息
CommonJs自定义模块的使用/npm 包 第三方模块/package.json版本信息
132 0
CommonJs自定义模块的使用/npm 包 第三方模块/package.json版本信息
|
XML JSON 缓存
自定义变量、Nginx 访问日志转换为 json 及 Nginx gzip 压缩功能(二)|学习笔记
快速学习自定义变量、Nginx 访问日志转换为 json 及 Nginx gzip 压缩功能
305 0
自定义变量、Nginx 访问日志转换为 json 及 Nginx gzip 压缩功能(二)|学习笔记