Json.Net系列教程 2.Net类型与JSON的映射关系
原文 Json.Net系列教程 2.Net类型与JSON的映射关系
首先谢谢大家的支持和关注.本章主要介绍.Net类型与JSON是如何映射的.我们知道JSON中类型基本上有三种:值类型,数组和对象.而.Net中的类型比较多.到底它们是如何映射的呢?
总体来讲,Json.Net将.Net中的基本类型(int,float,string等)转换为Json的值,数组和集合转换为Json的数组,其它转换为Json对象.
如果你自定义了实现了数组和集合的类,并为类添加了自己的属性,抱歉在序列化时,该属性不会被序列化.例如我定义了如下的集合:
- public class MyArray : ArrayList
- {
- public string Name { get; set; }
- }
实例化该类并序列化

- MyArray ma = new MyArray { Name = "myArray" };
- ma.Add();
- ma.Add();
- ma.Add();
- string json = JsonConvert.SerializeObject(ma);
- Console.WriteLine(json);

效果:
如果我想把数组以对象的形式序列化,可不可以呢?答案是肯定的!
只要在定义的数组类的前面加上特性"JsonObject"即可,当然先要引入命名空间"Newtonsoft.Json".
- [JsonObject]
- public class MyArray : ArrayList
- {
- public string Name { get; set; }
- }
结果:
是的,你会发现结果中没有我们添加的值了,并且多出了很多其他我们并没有定义的值,这是因为我们添加的值在ArrayList中是以私有数组来存储的,默认情况下,Json.Net是仅仅序列化公有成员的.多出来的值是继承的接口中的属性.
字典类型(Dictionary,IDictionary,Hashtable等)会被序列化为对象,是以其中的key/value的形式来序列化,额外添加的属性不会被序列化.这里不再详讲了.
在.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!有什么问题,请及时告诉我啊!一起学习!
Json.Net系列教程 2.Net类型与JSON的映射关系的更多相关文章
- Json.Net系列教程 3.Json.Net序列化和反序列化设置
原文 Json.Net系列教程 3.Json.Net序列化和反序列化设置 上节补充 首先补充一点,Json.Net是支持序列化和反序列化DataTable,DataSet,Entity Framewo ...
- Json.Net系列教程 1.Json.Net介绍及实例
原文 Json.Net系列教程 1.Json.Net介绍及实例 本系列教程假设读者已经对Json有一定的了解,关于Json在这里不多说.本系列教程希望能对读者开发涉及到Json的.Net项目有一定的帮 ...
- Json.Net系列教程 4.Linq To JSON
原文 Json.Net系列教程 4.Linq To JSON 更改历史 2013-05-31 添加一个FAQ 一.Linq to JSON是用来干什么的? Linq to JSON是用来操作JSO ...
- .NET 中,编译器直接支持的数据类型称为基元类型(primitive type).基元类型和.NET框架类型(FCL)中的类型有直接的映射关系.
.NET 中,编译器直接支持的数据类型称为基元类型(primitive type).基元类型和.NET框架类型(FCL)中的类型有直接的映射关系. The primitive types are Bo ...
- 使用Newtonsoft.json 解决 Asp.Net MVC DateTime类型数据Json格式化问题
解决思路 众所周知,MVC中调用的微软的组件JavaScriptSerialer...,格式DateTime类型数据需要在客户端专门解. 还知道,NewtonSoft.json可以“正确”的格式化Da ...
- JPA 系列教程14-自定义类型-@Embedded+@Embeddable
自定义类型 在hibernate中实现自定义类型,需要去实现UserType接口即可或者以Component的形式提供. JPA的@Embedded注解有点类似,通过此注解可以在Entity模型中使用 ...
- thinkphp5操作redis系列教程】列表类型之lRange,lGetRange
<?php namespace app\admin\controller; use think\cache\driver\Redis; use think\Controller; use \th ...
- JNI类型与C/C++映射关系
Java 类型 本地类型 描述 boolean jboolean C/C++8位整型 byte jbyte C/C++带符号的8位整型 char jchar C/C++无符号的16位整型 short ...
- 关系类型字段 -- Django从入门到精通系列教程
该系列教程系个人原创,并完整发布在个人官网刘江的博客和教程 所有转载本文者,需在顶部显著位置注明原作者及www.liujiangblog.com官网地址. Python及Django学习QQ群:453 ...
随机推荐
- matlab GUI之 -- 绘图
1.常用属性 linestyle: 实线 - 虚线 -- 点线 : 点画线 -. marker: 加号 + 圆圈 O 星号 * 方块 S 三角形 ^ < > 五角星 P color: ...
- CentOS6.4下安装JDK1.6
首先,切换到jdk安装包所在目录: [rot@centos6 Downloads]# ./jdk-6u45-linux-x64-rpm.bin Unpacking... Checksumming... ...
- 块对象block小结(2)
MRC环境下 //// main.m// blcok//// Created by ios on 16/4/6.// Copyright © 2016年 ios. All rights res ...
- ##DAY14——StoryBoard
•iOS下可视化编程分为两种⽅式:xib和storyboard. •在使用xib和storyboard创建GUI过程中,以XML文件格式 存储在Xcode中,编译时生成nib的二进制文件.在运行时, ...
- JSTL入门
在页面最上方引入 -------------------- if语句 8}"> b的值大于8 --------------------- foreach语句 i的值是:${i}
- JQuery中serialize() 序列化
更多2014/8/24 来源:jquery学习浏览量:1671 学习标签: serialize 本文导读:在jQuery中,当我们使用ajax时,常常需要拼装input数据以键值对(Key/Value ...
- PHP无法获取Referer问题排查
测试结果: 同一个页面,2次打开,第一次能获取到Referer第二次获取不到,很好奇原因所在. test1.php代码是: <?php echo '测试来源:直接载入页面<br/>' ...
- Python正则表达式指南(转载)
转载自:http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html#3353540 1. 正则表达式基础 1.1. 简单介绍 正则表达式并不 ...
- oracle plsql 64位 32位连接未打开 无法解析各种错终极解决方案
首先取消登陆,进入pl/sql界面-工具-首选项 其次就需要你设置环境变量(加一个ORACLE_HOME和修改原先path里的路径这个不修改也行,主要是让大家知道为什么设置环境变量) 这些设置好,你在 ...
- UPPH、UPH
UPPH=units Per Hour Per Person,单位小时人均产能,是公司作为衡量员工工作绩效的重要指标. UPPH是衡量员工单位时间工作量的一种绩效指标. UPPH计算方式如下: UPP ...