首先谢谢大家的支持和关注.本章主要介绍.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();
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是仅仅序列化公有成员的.多出来的值是继承的接口中的属性.

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!有什么问题,请及时告诉我啊!一起学习!

.Net类型与JSON的映射关系的更多相关文章

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

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

  2. .NET 中,编译器直接支持的数据类型称为基元类型(primitive type).基元类型和.NET框架类型(FCL)中的类型有直接的映射关系.

    .NET 中,编译器直接支持的数据类型称为基元类型(primitive type).基元类型和.NET框架类型(FCL)中的类型有直接的映射关系. The primitive types are Bo ...

  3. JNI类型与C/C++映射关系

    Java 类型 本地类型 描述 boolean jboolean C/C++8位整型 byte jbyte C/C++带符号的8位整型 char jchar C/C++无符号的16位整型 short ...

  4. 通过映射关系 动态转义为统一格式的数据 (支持 JSON 和 XML )

    在很多的时候 我们都会 需要 将不同格式的数据  转换为 统一的数据格式 比如 将Json 源数据 { "b": [ { "c": "referenc ...

  5. Mysql,Oracle与Java字段类型映射关系

    Mysql,Oracle与Java字段类型映射关系 参考相关博文 MySQL/Oracle字段类型 Java字段类型 最大长度 BIT java.lang.Boolean 1 BLOB java.la ...

  6. ASP.NET Core的路由[1]:注册URL模式与HttpHandler的映射关系

    ASP.NET Core的路由是通过一个类型为RouterMiddleware的中间件来实现的.如果我们将最终处理HTTP请求的组件称为HttpHandler,那么RouterMiddleware中间 ...

  7. EF里的继承映射关系TPH、TPT和TPC的讲解以及一些具体的例子

    本章节讲解EF里的继承映射关系,分为TPH.TPT.TPC.具体: 1.TPH:Table Per Hierarchy 这是EF的默认的继承映射关系:一张表存放基类和子类的所有列,自动生成的discr ...

  8. Hibernate关联映射关系

    Hibernate关联映射关系 一.双向一对多关联映射关系:当类与类之间建立了关联,就可以方便的从一个对象导航到另一个或另一组与它关联的对象(一对多双向关联和多对一双向关联是完全一样的) 1.1创建实 ...

  9. 注册URL模式与HttpHandler的映射关系

    注册URL模式与HttpHandler的映射关系 ASP.NET Core的路由是通过一个类型为RouterMiddleware的中间件来实现的.如果我们将最终处理HTTP请求的组件称为HttpHan ...

随机推荐

  1. Margin是什么?

    Margin是什么 CSS 边距属性定义元素周围的空间.通过使用单独的属性,可以对上.右.下.左的外边距进行设置.也可以使用简写的外边距属性同时改变所有的外边距.——W3School 边界,元素周围生 ...

  2. 创建一个简单的配置android编译环境的脚本

    由于有多个Android项目,每个项目配置编译环境时选项都不同,所以尝试写一个sh脚本来完成这个功能.     首先进入bin文件夹,新建一个文件enbuild $ cd ~/bin $ touch ...

  3. windows xp通过VNC viewer远程连接RHEL5桌面

    环境: [root@localhost ~]# cat /etc/issue Red Hat Enterprise Linux Server release 5.2 (Tikanga) Kernel ...

  4. C#实现在线更新系统

    先来看一下程序完成后长什么样. 这个是程序的组成部分. 主要功能是在InitializationUpdate这个类中完成的,From1主要起到调用的作用,所以重心还是在InitializationUp ...

  5. winsock开发重复定义问题

    参考: VS2013使用winsock.h和winsock2.h发生冲突后的终极解决方法:http://www.cnblogs.com/Shirlies/p/5137548.html WINSOCK. ...

  6. 求一无序数组中第n大的数字 - 快速选择算法

    逛别人博客的时候,偶然看到这一算法题,顺便用C++实现了一下. 最朴素的解法就是先对数组进行排序,返回第n个数即可.. 下面代码中用的是快速选择算法(不晓得这名字对不对) #include <v ...

  7. [Leetcode] Find the minimum in rotated sorted array

    我在Github上新建了一个解答Leetcode问题的Project, 大家可以参考, 目前是Java 为主,里面有leetcode上的题目,解答,还有一些基本的单元测试,方便大家起步. 题目: Su ...

  8. IOS通过PushSharp开源框架发送推送

    1,首先生成推送证书: openssl x509 -in aps_developer_identity.cer -inform DER -out aps_developer_identity.pem ...

  9. gulp压缩js

    1.安装nodejs -> 全局安装gulp -> 项目安装gulp以及gulp插件 -> 配置gulpfile.js -> 运行任务 2.查看nodejs的版本号 3.npm ...

  10. bootstrap模态框垂直居中

    很久没有写东西了,之前想写一些移动端的东西以后补上吧,移动端发展还是蛮快的,回正题. 因为最近在弄一个系统,系统中引用了bootstrap,发现模态框垂直不居中,遂搜索了一下,也都试了一下,无非都是在 ...