博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Json.Net系列教程 2.Net类型与JSON的映射关系
阅读量:4939 次
发布时间:2019-06-11

本文共 4311 字,大约阅读时间需要 14 分钟。

原文

首先谢谢大家的支持和关注.本章主要介绍.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
members = new Dictionary
(); ///
/// 获取所有的动态成员名称 /// ///
动态成员名称
public override IEnumerable
GetDynamicMemberNames() { return members.Keys; } ///
/// 设置动态成员名称,也就是在发生赋值语句时出发该方法 /// 例如:dynamic dy = new MyDynamic(); /// dy.Name = "Jack"; /// ///
用于动态设置操作 ///
预设的值 ///
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; } ///
/// 根据名称获取动态成员的值 /// 例如:dynamic dy = new MyDynamic(); /// var name = dy.Name; /// ///
用户动态获取操作 ///
将获取的值赋给的对象 ///
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); } ///
/// 如果成员的类型是委托,则调用它 /// ///
用户动态委托操作 ///
委托调用的参数 ///
委托调用返回的结果 ///
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
output = new Action
((value) => { Console.WriteLine(value); }); md.Output = output; Console.WriteLine(JsonConvert.SerializeObject(md)); md.Output(md.Name);

结果:

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

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

此时的运行结果:

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

posted on
2013-11-01 22:58 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/lonelyxmas/p/3402986.html

你可能感兴趣的文章
固定资产管理系统 概要说明书说明书
查看>>
类的绑定方法
查看>>
2016-5-25授课(3)
查看>>
新增加的元素 相关操作获取不到
查看>>
Zabbix 3.0编译安装
查看>>
json介绍及简单示例
查看>>
h.264 率失真优化
查看>>
【转】拓扑排序入门
查看>>
Spring中Bean的命名问题(id和name区别)及ref和idref之间的区别
查看>>
How to install 64-bit Google Chrome 28+ on 64-bit RHEL/CentOS 6 or 7
查看>>
搭建LNAMP环境(三)- 源码安装Apache2.4
查看>>
linux --> fork()详解
查看>>
Spring注解 开发
查看>>
#!/bin/bash(转)
查看>>
BZOJ4589 Hard Nim(博弈+FWT)
查看>>
hdu 2473 Junk-Mail Filter 并查集删点,模板题
查看>>
【Maps】【搜狗】
查看>>
Linux命令详解-whatis
查看>>
分组求和
查看>>
eclipse 忽略 target 设置
查看>>