Json.Net系列教程 2.Net类型与JSON的映射关系

简介: 原文 Json.Net系列教程 2.Net类型与JSON的映射关系 首先谢谢大家的支持和关注.本章主要介绍.Net类型与JSON是如何映射的.我们知道JSON中类型基本上有三种:值类型,数组和对象.而.

原文 Json.Net系列教程 2.Net类型与JSON的映射关系

首先谢谢大家的支持和关注.本章主要介绍.Net类型与JSON是如何映射的.我们知道JSON中类型基本上有三种:值类型,数组和对象.而.Net中的类型比较多.到底它们是如何映射的呢?

总体来讲,Json.Net将.Net中的基本类型(int,float,string等)转换为Json的值,数组和集合转换为Json的数组,其它转换为Json对象.

1.基本类型:

2.复杂类型:

3.注意
3.1数组和集合

如果你自定义了实现了数组和集合的类,并为类添加了自己的属性,抱歉在序列化时,该属性不会被序列化.例如我定义了如下的集合:

    public class MyArray : ArrayList
    {
        public string Name { get; set; }
    }

实例化该类并序列化

复制代码
            MyArray ma = new MyArray { Name = "myArray" };
            ma.Add(1);
            ma.Add(2);
            ma.Add(3);
            string json = JsonConvert.SerializeObject(ma);
            Console.WriteLine(json);
复制代码

效果:

如果我想把数组以对象的形式序列化,可不可以呢?答案是肯定的!
只要在定义的数组类的前面加上特性"JsonObject"即可,当然先要引入命名空间"Newtonsoft.Json".

    [JsonObject]
    public class MyArray : ArrayList
    {
        public string Name { get; set; }
    }

结果:

 是的,你会发现结果中没有我们添加的值了,并且多出了很多其他我们并没有定义的值,这是因为我们添加的值在ArrayList中是以私有数组来存储的,默认情况下,Json.Net是仅仅序列化公有成员的.多出来的值是继承的接口中的属性.

3.2字典类型

字典类型(Dictionary,IDictionary,Hashtable等)会被序列化为对象,是以其中的key/value的形式来序列化,额外添加的属性不会被序列化.这里不再详讲了.

3.3Dynamic类型

在.Net4.0中,Dynamic基本上有两种用法.
一种是作为属性来用,在这种情况下序列化时会根据实际的类型来序列化.
第二 种用法是继承了IDynamicMetaObjectProvider 接口或者DynamicObject 基类,例如.Net中内置的类ExpandoObject ,这三者之间的关系是:ExpandoObject,DynamicObject都继承了IDynamicMetaObjectProvider.这种情 况下,只有DynamicMetaObject.GetDynamicMemberNames的返回的成员的属性会被序列化.

 首先新建一个类,继承基类 DynamicObject

复制代码
    public class MyDynamic : DynamicObject
    {
        //用来存储动态添加的变量和值
        private Dictionary<string, object> members = new Dictionary<string, object>();

        /// <summary>
        /// 获取所有的动态成员名称
        /// </summary>
        /// <returns>动态成员名称</returns>
        public override IEnumerable<string> GetDynamicMemberNames()
        {
            return members.Keys;
        }

        /// <summary>
        /// 设置动态成员名称,也就是在发生赋值语句时出发该方法
        /// 例如:dynamic dy = new MyDynamic();
        /// dy.Name = "Jack";
        /// </summary>
        /// <param name="binder">用于动态设置操作</param>
        /// <param name="value">预设的值</param>
        /// <returns></returns>
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            if (!members.ContainsKey(binder.Name))
            {
                members.Add(binder.Name, value);
            }
            else
                members[binder.Name] = value;
            return true;
        }

        /// <summary>
        /// 根据名称获取动态成员的值
        ///  例如:dynamic dy = new MyDynamic();
        ///  var name = dy.Name;
        /// </summary>
        /// <param name="binder">用户动态获取操作</param>
        /// <param name="result">将获取的值赋给的对象</param>
        /// <returns></returns>
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            if (members.ContainsKey(binder.Name))
            {
                result = members[binder.Name];
                return true;
            }
            else
                return base.TryGetMember(binder, out result);
        }

        /// <summary>
        /// 如果成员的类型是委托,则调用它
        /// </summary>
        /// <param name="binder">用户动态委托操作</param>
        /// <param name="args">委托调用的参数</param>
        /// <param name="result">委托调用返回的结果</param>
        /// <returns></returns>
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            if (members.ContainsKey(binder.Name) && members[binder.Name] is Delegate)
            {
                result = (members[binder.Name] as Delegate).DynamicInvoke(args);
                return true;
            }
            else
            {
                return base.TryInvokeMember(binder, args, out result);
            }
        }
    }
复制代码

在主程序中,做如下操作:

复制代码
            dynamic md = new MyDynamic();//必须是用dynamic来声明变量,不能用MyDynamic,否则它就不是动态类型了。
              md.Name = "Jack";
            Action<string> output = new Action<string>((value) => { Console.WriteLine(value); });
            md.Output = output;
            Console.WriteLine(JsonConvert.SerializeObject(md));
            md.Output(md.Name);
复制代码

结果:

是的,委托类型也被序列化了,这并不是我们想要的,有没有方法来将它排除呢?答案就在GetDynamicMemberNames方法,默认我们返回的是所有的Keys,只要我们加一定的限制条件即可.修改之后的代码

复制代码
        public override IEnumerable<string> GetDynamicMemberNames()
        {
            foreach (string key in members.Keys)
            {
                if(!(members[key] is Delegate))
                    yield return key;
            }
        }
复制代码

此时的运行结果:

 OK!有什么问题,请及时告诉我啊!一起学习!

目录
相关文章
|
24天前
|
开发框架 前端开发 JavaScript
ASP.NET Web Pages - 教程
ASP.NET Web Pages 是一种用于创建动态网页的开发模式,采用HTML、CSS、JavaScript 和服务器脚本。本教程聚焦于Web Pages,介绍如何使用Razor语法结合服务器端代码与前端技术,以及利用WebMatrix工具进行开发。适合初学者入门ASP.NET。
|
1月前
|
JSON Java 数据格式
springboot中表字段映射中设置JSON格式字段映射
springboot中表字段映射中设置JSON格式字段映射
142 1
|
2月前
|
开发框架 NoSQL MongoDB
C#/.NET/.NET Core开发实战教程集合
C#/.NET/.NET Core开发实战教程集合
|
2月前
|
存储 NoSQL API
.NET NoSQL 嵌入式数据库 LiteDB 使用教程
.NET NoSQL 嵌入式数据库 LiteDB 使用教程~
|
3月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
51 7
|
3月前
|
SQL 关系型数据库 数据库
七天.NET 8操作SQLite入门到实战详细教程(选型、开发、发布、部署)
七天.NET 8操作SQLite入门到实战详细教程(选型、开发、发布、部署)
|
4月前
|
JSON 开发框架 JavaScript
【Azure Developer】使用.Net Core解析JSON的笔记
【Azure Developer】使用.Net Core解析JSON的笔记
|
4月前
|
开发框架 .NET API
在IIS上部署ASP.NET Core Web API和Blazor Wasm详细教程
在IIS上部署ASP.NET Core Web API和Blazor Wasm详细教程
215 3
|
4月前
|
存储 C#
揭秘C#.Net编程秘宝:结构体类型Struct,让你的数据结构秒变高效战斗机,编程界的新星就是你!
【8月更文挑战第4天】在C#编程中,结构体(`struct`)是一种整合多种数据类型的复合数据类型。与类不同,结构体是值类型,意味着数据被直接复制而非引用。这使其适合表示小型、固定的数据结构如点坐标。结构体默认私有成员且不可变,除非明确指定。通过`struct`关键字定义,可以包含字段、构造函数及方法。例如,定义一个表示二维点的结构体,并实现计算距离原点的方法。使用时如同普通类型,可通过实例化并调用其成员。设计时推荐保持结构体不可变以避免副作用,并注意装箱拆箱可能导致的性能影响。掌握结构体有助于构建高效的应用程序。
142 7
|
5月前
|
存储 JSON 数据格式
Python教程:json中load和loads的区别
【7月更文挑战第17天】在Python的`json`模块中, `load`与`loads`函数均用于JSON至Python对象的转换, 区别在于: - **`loads`**处理JSON格式的**字符串** 其中`data.json`文件内容为`{&quot;name&quot;: &quot;Bob&quot;, &quot;age&quot;: 30}`。 简而言之, `loads`用于字符串, 而`load`用于文件对象。根据数据来源选择合适的方法。
130 5

热门文章

最新文章