Json的种类化与反连串化,使用dynamic类型来访问JObject对象

dynamic是C#内部的动态类型,可在不为人知类型的图景走访对应的性质,万分灵活和有利于。

上篇作品”理解C# 4 dynamic(2) –
ExpandoObject的使用” 领会了ExpandoObject的宗旨使用。

Json的连串化与反种类化,Json系列化体系化

  想想某1天,你在看英雄结盟战略的时候,系统突然崩溃了,接着浏览器出现了层层的LOL帐号和密码,你确定在想:“天啊,这一次要发财了,说不定里面有超脱凡俗号可能王者号,笔者得赶紧全体记下来。”然则说完你就惊呆了,那么多的帐号密码,而且全部写在了Json里面,2个1个复制粘贴要记到如何时候啊。。。假若此时小编在你身边,我自然会推推搡搡您的,前提是,要分多少个王者号给小编噢。。。

  亚洲必赢官网 1

 

   言归正传。

  上边举的事例即使有点不太现实,但实际是想和豪门证澳优个难题,假若要解析Json或XML,请不要选用检索字符串的不二秘技!!!

     
 那么在验证什么解析Json和XML在此以前,我们先来搞精通多个概念:序列化反种类化

     
「系列化,即Serialization,是一个将目的的意况音讯转变为能够积累或传输的花样的历程。」

 
  「反类别化,即Deserialization,顾名思义是叁个将可以积存或传输的行列浮动为某些对象的情状音信的过程。」

  从地点的概念,大家得以得出五个结论:

  1 那七个进度互为逆进程;

  贰 无论是体系化照旧反类别化,对象的情景新闻都与一段体系相呼应。

  上边大家就来看望哪些用C#言语实行Json和XML的系列化和反系列化。

  

   Json的系列化与反系列化

   ① 使用Newtonsoft.Json库

  首先大家先来看一段代码:

 1 public void JsonDeserialize(string jsonString)
 2 {
 3     //Json的反序列化操作
 4     JObject jObject = JsonConvert.DeserializeObject(jsonString) as JObject;
 5     //清空listBox的结果
 6     listBoxResult.Items.Clear();
 7     //将解析得到的数据显示到listBox中
 8     listBoxResult.Items.Add("Name : " + jObject["name"] ?? "null");
 9     listBoxResult.Items.Add("Doing : " + jObject["doing"] ?? "null");
10     listBoxResult.Items.Add("HandleContent : " + jObject["handleContent"] ?? "null");
11     listBoxResult.Items.Add("DateTime : " + jObject["dateTime"] ?? "null");
12 }

  下面那么些点子的成效是,接收一段Json类别作为参数,在实现行反革命类别化后,将具有字段的值输出到ListBox中,上面是差不多的测试:

  亚洲必赢官网 2

  能够观察,仅仅用了壹行代码,Json的内容就根据字段全都被获取到了,上边就来好好了结一下Newtonsoft.Json那个库的用法吧。

  Newtonsoft.Json是.NET平台北多个可怜流行且高品质的Json体系化和反体系化开源库,提供了成都百货上千用于体系化和反种类化Json的类及方法,除却它还提供了用Linq操作Json、将Json转变来XML的功用,相较于古板的用来类别化和反体系化的DataContractJsonSerializer类更加好用,更火速。本文只介绍个中比较关键的JsonConvert类和多少个常用的档期的顺序,更加多内容大家能够访问Json.NET的主页实行询问。

  在介绍使用办法前,先来讲说Newtonsoft.Json.dll的引进。从VS20一叁从头,ASP.NET的连串均自带了Newtonsoft.Json.dll,直接运用就能够,而别的版本或然别的项目只要没有的话,能够进去其官方主页,找到Github托管的地方进入并下载。上面演示引用该动态链接库的流程,

  一点击菜单栏的档案的次序->增添引用,可能在化解方案财富管理器中找到项目,右键引用属性,点击增添引用,然后就能展开该窗口。

  该窗口展开后,假若是率先次加多Newtonsoft.Json.dll,请找到右下方的浏览开关,并选用Newtonsoft.Json.dll;若在此以前增加过该库,能够点击左侧的浏览菜单,并点击近来,右边会来得从前添加过的库的音信,勾上必要的库,末了点击右下方的规定就可以。

  亚洲必赢官网 3

  

  增加了动态链接库还没完,要想利用当中的类和格局,必要引进相应的命名空间(假让你不想每定义3个目的就写一长串命名空间的话),本文主要选拔的命名空间是Newtonsoft.Json以及Newtonsoft.Json.Linq

  亚洲必赢官网 4

  完结那两步之后就能够舒舒服服的初阶解析大家巨大的Json了。

  Now,先来介绍本库相比重大的类,JsonConvert。JsonConvert是个越发实用的工具类,它提供了用来反种类化的DeserializeObject方法和DeserializeObject<T>方法,以及用于类别化的SerializeObject方法。由于那几个格局都以静态方法,因而无需创制JsonConvert对象,直接使用妥妥的(事实上JsonConvert是个静态类,根本不也许被实例化)。

  在最早先演示的例子中,大家应用了JsonConvert.DeserializeObject方法,那是最原始的Json反类别化方法,它接受string类型的参数并再次来到object类型的目的。那么你或然会问到,它回到的靶子毕竟是何等类型???想要真正获得该目的的音信,就亟须将其强制转换来具体的派生类。那么,大家可以使用GetType方法来一探毕竟。

1 private void btnDeserialize_Click(object sender, EventArgs e)
2 {
3     //JsonDeserialize(textBox1.Text);
4     var secretObject = JsonConvert.DeserializeObject(textBox1.Text);
5     MessageBox.Show(secretObject.GetType().ToString());
6 }

   大家先在叁个按钮的点击事件对应的方法中分析输入的Json类别,由于大家还不鲜明JsonConvert.DeserializeObject方法重临什么目的,因而大家先用隐式类型对象去引用该形式再次回到的结果,然后调用其GetType方法,获取该对象所属类型的元数据,最终将目标的完全类型名显示在对话框其中。实行那段代码,你将会看出如下结果:

  亚洲必赢官网 5

  或然那时候在您的内心又有20000个草泥马呼啸而过,“What?还没搞清楚JsonConvert类的用法,怎么又跑出了二个奇异的类?”

  可是没什么,接下去笔者会对我们的谜团实行每种的分解。

   在Newtonsoft.Json.Linq命名空间中,定义了部分用于表示差别样式的Json字符串的类,它们包蕴JObject、JProperty、JToken、JArray、JValue、JContainer等等。

       
那么在这一个类在那之中,JToken充当着标杆的剧中人物,它是二个抽象类,并促成了IJEnumerable<T>接口,而IJEnumerable<T>接口承袭自IEnumerable<T>接口,那表示所有继续JToken的类都足以动用foreach语句实行遍历,而接下去要介绍的这几个类,全都派生自JToken。别的,JToken还定义了First、Last、Parent、Root、Item、Previous、Next等遍历平常会用到的性质,由此在利用那几个类的时候,遍历、查找具体类等操作就显得相当的总结。说了这样多,是时候说说JObject了,那是个JToken的派生类,同时也是促成了JContainer接口、ICollection<T>、IKeyValuePair<T>,这意味JObject能够积存多少个持续JToken类型的靶子,同时也足以遍历它们,还是能够用键去赚取相应的值,可能你还不驾驭这几个有哪些用,那么大家先来询问一下Json的主干结构:

  一般的话,被大括号括起来的始末能够看作是一个完好无缺的(2个对象的),而被中括号括起来的剧情,能够看做是一组内容(一个数组),在2个繁杂的Json结构中,大括号里面的有些键的值能够在嵌贰个大括号,代表该属性值为另3个Json对象,同理三个大括号中的有个别键的值能够嵌二个中括号,代表该属性值是三个数组,如

 1 //对于这种Json来说,可以看成是一个对象,里面包含了name、doing、handleContent和dateTime属性。
 2 {
 3     "name":".NET Coder",   
 4     "doing":"Deserialization",
 5     "handleContent":"Json",
 6     "dateTime":"2017-09-11 12:12:12"
 7 }
 8 
 9 //对于这种Json来说,可以看成是一个数组对象,里面包含了两个对象。
10 [
11   {
12     "name":".NET Coder",   
13     "doing":"Deserialization",
14     "handleContent":"Json",
15     "dateTime":"2017-09-11 12:12:12"
16   },
17   {
18     "name":"Java Coder",   
19     "doing":"Deserialization",
20     "handleContent":"Json",
21     "dateTime":"2017-09-22 21:21:21"
22   }
23 ]

  在上3个演示的事例中,大家用GetType方法去决断达成反体系化之后,实际再次来到的花色是哪些;那么接下去大家就将地点那二种区别结构的Json类别放入程序中剖析,看看得到的目的是否都是JObject。

  亚洲必赢官网 6

      成功获取了JObject类型的目的。

  亚洲必赢官网 7

  本次大家居然获得了JArray?!

  这下大家大概就理解了,JObject用于表示3个完整的Json对象组织,而JArray用于表示二个Json数组,个中会席卷二个或三个Json对象。

  在获取JObject对象之后,大家得以用属性名(键)去获取相应的属性值,也能够使用Next、Previous等属性去家家户户访问JObject的习性。

  而收获JArray对象之后,大家得以动用for恐怕foreach语句去遍历该对象内的因素,然后依据有个别属性名或Next、Previous等质量去访问当前因素某些属性的属性值。

  那么JProperty和JValue类型又有如何意义吗?

  大家能够来调度一下先后,并注重JObject对象内的布局,

亚洲必赢官网 8

  如图大家在运用foreach循环遍历JObject内部的习性,能够见到,First属性指向了JObject的率先个性格,而它的花色是JProperty,由此大家得以领略,JProperty类用于描述三个Json对象中的某一性格质,在个中间含有了四个KeyValuePair<string,
JToken>的分子变量,用于存款和储蓄该Json属性的键值对,而那几个值,其实正是JValue类型的变量。

亚洲必赢官网 9

  

  那么到这里结束,大家已经精通了DeserializeObject方法的用法了,不过很掌握,那种格局解析Json数据实际上太麻烦了,大家须求把全数Json对象的性质2个个赢获得,然后本领赢得在那之中的值,有没有更简单介绍的法子呢?

  有!有!有!首要的工作说三遍。

  上边该轮到DeserializeObject<T>方法出场了,这是个泛型方法,钦命T的品种并传播Json字符串作为参数后,该方法会落成反种类化并赶回一个T类型的目的。那么大家该钦命什么品种给该措施吗?这几个体系须要依照Json数据的层系关系自行设计,假设大家是率先次使用,不精晓该如何统一准备,那么大家来让VS帮大家统一希图,上面给大家介绍2个奇妙的机能,VS的自动建类功效:

  照旧那段Json类别,即便大家供给将其反系列化,以后却不明了怎么设计类,那么我们得以先复制这段Json种类,

1 {
2     "name":".NET Coder",   
3     "doing":"Serialization",
4     "handleContent":"Json",
5     "dateTime":"2017-09-11 12:12:12"
6 }

  张开VS,在菜单栏找到编辑->接纳性粘贴,点击将Json粘贴为类,就能够现出下边的结果,

亚洲必赢官网 10

亚洲必赢官网 11

  原本空白的地点,突然出现了三个类的概念(假诺Json有三个层级,VS会帮大家转移多少个类),那个类清晰的显示了那段Json的布局,此时大家只须要将以此自动生成的类,用到艺术里就好了:

Json的种类化与反连串化,使用dynamic类型来访问JObject对象。  亚洲必赢官网 12

  亚洲必赢官网 13 

  大家改写了JsonDeserialize方法,并利用了由VS生成的类,能够看出我们没有需求再依据属性名去获得属性值了,也不用再顾忌忘记有哪些性质或然属性名写错,只须求在对象后边加上一些,该目的的享有属性都会现出在选取列表中。是否出人意料认为日前1亮,壹身轻便了啊?但实际这些做法隐藏了一丢丢小意思,因为VS是依赖Json原来的属性名来定义属性的,那就要求Json的性质名遵从C#的标记符定义规则,然后实际,在Json中也许会产出不符合C#标志符定义标准的属性名,那并从未错,如上边那段Json:

1 {
2     "name":"money",   
3     "price":"66.6",
4     "int":"64",
5     "a-b":"c-d",
6     "@#$":"sdfsdf"
7 }

亚洲必赢官网 14

  能够观望,纵然VS会用_去顶替非法的字符串并服从专门的学业生成属性名,然则那样子的属性名已经错过了它的含义,大家不恐怕获悉这性格子表明了哪些含义,为了缓慢解决那几个主题材料,我们得以使用C#的申明来给该类的品质制定数码协定

  亚洲必赢官网 15

 

  
DataContract和DataMember表明来自于命名空间System.Runtime.Serialization,这么些命名空间所在的动态链接库项目私下认可是从未有过引进的,需求手动引进,大家只必要遵循上边引进牛顿soft.Json.dll的主意引进就好,但是急需注意的是,System.Runtime.Serialization所在的动态链接库在VS程序集中是提供了的,大家只需求在充分引用分界面,点击程序集,并在左侧的列表找到System.Runtime.Serialization并勾选,然后点击右下角的规定按键就可以。

  达成那个步骤之后我们就足以改变Json的实体类,为其充足数据协定。什么是数据协定吗,即数据的发送方和接收方没有须要选用同一的品类,只须要根据数据协定就能够。为了使该类能够加多数据协定,需求在类名上方增加[DataContract]评释,表达该类的习性使用了数额协定,并且同意将此类实行类别化,若果不加这些评释,就不可能使用[DataMember]注解了。添加[DataContract]疏解后,大家就足以在对应的属性上增多[DataMember]注明,该申明有多个参数:

参数名 作用
Name 标识该属性对应的Json属性名
Order 标识该属性序列化和反序列化的顺序
IsRequired 标识该属性在读取或反序列化时是否必须存在,类型为bool
EmitDefaultValue 标识在序列化的过程中是否使用该属性的默认值来序列化

 

  上图大家选取了Name参数来安装每一种属性对应的Json属性名,从而加强了此类在程序中的可读性,同时又不会对连串化和反系列化的长河发生麻烦。上面再改写一下JsonDeserialize方法吗:

  亚洲必赢官网 16

   亚洲必赢官网 17

  测试成功!!!

   其它再补偿五个小知识,当大家必要反种类化诸多轻巧的Json时,为了制止成立过多的实体类,咱们能够动用dynamic动态类型来顶替自定义的实体类,在此处大家改写上述例子,使用dynamic类型来兑现相应成效:

  亚洲必赢官网 18

 

  在这么些事例中,笔者未曾定义新的类,而是接纳了动态类型,那体系型的靶子有二个特征:运营时检查。在动用那种对象的时候我们要小心,无论是使用它的属性,依旧调用它的方法,编写翻译器都不会对其开始展览编写翻译时检查,也正是说大家必须保障属性名大概措施名尚未写错,不然会现出表明式为空大概吸引那么些的现象。

  亚洲必赢官网 19

   亚洲必赢官网 20

  调用不设有的习性重返Null。

 

  亚洲必赢官网 21

  调用不设有的法门引发那些。

 

  亚洲必赢官网 22

  在一贯不不当的动静下,成功运转!

  

  到此处反体系化的介绍算是告一段落了,接下去大家讲讲使用JsonConvert.SerializeObject方法成功体系化操作。

  前面那么多操作的目标是为精晓析Json字符串,让我们能有益的拿走个中的音讯,不过倘若大家不是新闻的接收方而是发送方呢,大家要怎么布局Json字符串?显然不容许用字符串拼接的法子,成效低下,难以排错。因而后日我们将要用壹行代码来完结那件专门的学问。

  

亚洲必赢官网,  亚洲必赢官网 23

 

  没有错,就唯有一行代码!!!

 

  亚洲必赢官网 24

  亚洲必赢官网 25

  看呢,是还是不是单排代码就让贰个属实的对象弹指间变为了一串Json了吧!!!

  

  ② 使用DataContractJsonSerializer类

  其实本身并不想讲解那么些类,第一利用进程十一分麻烦,第三效用低下,实际专业中也不会用它,但是从上学的角度大家依旧要打听一下以此类的留存,并且那些类系列化和反类别化Json的进程和XML的连串化和反种类化很相像,由此依然有至关重要让咱们探听一下。

  在此不多说其余废话,间接上代码:

  DataContractJsonSerializer序列化

 1 public void OldJsonSerialize()
 2 {
 3     DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(HandleObject));
 4     //创建实体类
 5     HandleObject jObject = new HandleObject() {
 6         Name = ".NET Coder",
 7         Doing = "Serialization",
 8         HandleContent = "Json",
 9         DateTime = DateTime.Now.ToString("yyyy-MM-ss")
10     };
11     //创建内存流,用于存储序列化后得到的内容
12     MemoryStream ms = new MemoryStream();
13     //将对象序列化后存入内存流
14     serializer.WriteObject(ms, jObject);
15     //将内存流的内容转换成字符串并输出到文本框
16     textBox1.Text = Encoding.UTF8.GetString(ms.ToArray());
17 }

亚洲必赢官网 26

 

  DataContractJsonSerializer反种类化

 1 public void OldJsonDeserialize()
 2 {
 3     DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(HandleObject));
 4     //将Json字符串转换成字节数组
 5     byte[] content = Encoding.UTF8.GetBytes(textBox1.Text);
 6     //用字节数组初始化一个内存流对象
 7     MemoryStream ms = new MemoryStream(content);
 8     //完成反序列化操作
 9     HandleObject handleObject = serializer.ReadObject(ms) as HandleObject;
10     //将解析得到的数据显示到listBox中
11     listBoxResult.Items.Add("Name : " + handleObject.Name ?? "null");
12     listBoxResult.Items.Add("Doing : " + handleObject.Doing ?? "null");
13     listBoxResult.Items.Add("HandleContent : " + handleObject.HandleContent ?? "null");
14     listBoxResult.Items.Add("DateTime : " + (handleObject.DateTime.ToString() ?? "null"));
15 }

 

  DataContractJsonSerializer类和JsonConvert类最大的不一致就在于,DataContractJsonSerializer类将操作流的细节揭穿了出来,要求由用户自行完结,相比JsonConvert直接行使字符串要麻烦不少。

想想某1天,你在看英雄联盟攻略的时候,系统突然崩溃了,接着浏览器出现了数以万计的LOL帐号和密…

  想想某一天,你在看英雄缔盟战略的时候,系统突然崩溃了,接着浏览器出现了密密麻麻的英雄缔盟帐号和密码,你早晚在想:“天啊,本次要发财了,说不定里面有超凡号或许王者号,小编得赶紧全体记下来。”不过说完你就惊呆了,那么多的帐号密码,而且整个写在了Json里面,一个二个复制粘贴要记到何以时候呀。。。纵然此刻小编在你身边,小编自然会推抢您的,前提是,要分多少个王者号给笔者噢。。。

使用Json.Net能够把二个Json字符串转变来一个JObject对象,假设有已知强类型,如若有已知对应的强类型,能够直接转成对应的项目。但万壹未有,要访问Json个中对应的数目标时候,就呈现比较麻烦。我们得以借助DynamicObject来拜会对应的属性。

但ExpandoObject的难题正是它是3个万金油,什么都能够做,但是又都不留神。

  亚洲必赢官网 27

DynamicObject

笔者们要开创二个动态类,用于访问JObject,代码如下:

public class JObjectAccessor : DynamicObject
{
    JToken obj;

    public JObjectAccessor(JToken obj)
    {
        this.obj = obj;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        result = null;

        if (obj == null) return false;

        var val = obj[binder.Name];

        if (val == null) return false;

        result = Populate(val);

        return true;
    }


    private object Populate(JToken token)
    {
        var jval = token as JValue;
        if (jval != null)
        {
            return jval.Value;
        }
        else if (token.Type == JTokenType.Array)
        {
            var objectAccessors = new List<object>();
            foreach (var item in token as JArray)
            {
                objectAccessors.Add(Populate(item));
            }
            return objectAccessors;
        }
        else
        {
            return new JObjectAccessor(token);
        }
    }
}

 

接下去就能够开端利用它了:

string json = @"{'name': 'Jeremy Dorn','location': {'city': 'San Francisco','state': 'CA'},'pets': [{'type': 'dog','name': 'Walter'}]}";

JObject jobj = JObject.Parse(json);

dynamic obj = new JObjectAccessor(jobj);

Console.WriteLine($"{obj.name}: {obj.location.city} {obj.location.state}");
Console.WriteLine($"{obj.pets[0].type}: {obj.pets[0].name}");

 

运行一下程序,看一下出口结果:

亚洲必赢官网 28

原稿地址:

应用DynamicObject正好可以解决这一个题目。那篇小说介绍DynamicJson是什么样延续DynamicObject,包装一个用来拍卖Json的动态类型。

 

 

   言归正传。

翻阅目录:

壹、JS能够灵活管理Json字符串

二、DynamicObject分析

三、DynamicJson代码

四、总结

  上边举的事例纵然有点不太现实,但实质上是想和豪门证Bellamy(Bellamy)个主题材料,如若要解析Json或XML,请不要接纳检索字符串的措施!!!

一,JS能够灵活管理Json字符串

看上边包车型客车代码,

var jsonString='{"foo":"json", "bar":100, "nest":{ "foobar":true }}';
var jsonObj = JSON.parse(jsonString);
//接着就能方便的使用
jsonObj.foo
jsonObj.nest.foobar 

代码中的jsonObj是动态类型,在.net中,我们也得以反系列化Json,但都急需钦点反类别化后的对象类型。

举例接纳Json.Net

Newtonsoft.Json.JsonConvert.DeserializeObject(json, typeof(employee))

有未有法子和js一样,反连串化1个dynamic类型来方便的拜访Json数据?

下边先来探视DynamicObject怎么着利用,然后利用DynamicObject来贯彻大家的主张。

 

     
 那么在证实怎么样解析Json和XML在此之前,大家先来搞精通八个概念:序列化反种类化

二,DynamicObject分析

DynamicObject有个构造函数,不过protected,
也便是大家平素不主意直接实例化来利用它。只好是透过三番五次来布局DynamicObject的对象。

 

并且DynamicObject中很很多标记为Virtual的不二等秘书籍,比方:

public virtual bool TryGetMember(GetMemberBinder binder, out object result);

public virtual bool TrySetMember(SetMemberBinder binder, object value);

当大家写个类承袭DynamicObject,
这几个动态类型类的目的,所全数的特点,正是通过重写那个virtual方法体现出来的。

 

假设SampleObject 是继承DynamicObject的类,那么

假使我们重写了TryGetMember, 在调用 int number =
sampleObject.Number.时,就能够调用TryGetMemeber方法来赢得重返值。

一经我们重写了TrySetMember,在调用sampleObject.Number = number
时利用,就能够调用TrySetMember方法。

 

打探了DynamicObject, 大家的门径就愈加鲜明了:

笔者们要写一个类DynamicJson,承袭自DynamicObject

DynamicJson有静态Parse方法,接受五个Json的字符串,重返DynamicJson的指标。

DynamicJson重写TryGetMember方法,那样当访问属性的时候,大家管理,再次回到正确的值。

     
「种类化,即Serialization,是二个将对象的状态音信转变为能够储存或传输的样式的进程。」

三,DynamicJson代码

DynamicJson就是以此思路完毕的,下边来分析一下DynamicJson中有些注重代码

 
  「反体系化,即Deserialization,顾名思义是三个将可以积攒或传输的行列扭转为有些对象的状态新闻的过程。」

Parse静态方法

这段代码卓殊轻巧领悟,这里将json以xml格局管理,属性改为了xml中的element管理

亚洲必赢官网 29

public static dynamic Parse(string json)
{
    using (var reader = JsonReaderWriterFactory.CreateJsonReader(Encoding.Unicode.GetBytes(json), XmlDictionaryReaderQuotas.Max))
    {
        return ToValue(XElement.Load(reader));
    }
}

亚洲必赢官网 30

  从地方的概念,大家能够得出几个结论:

ToValue方法

To
value方法依照json反连串化后的xml音信,获取element的type属性,然后根据属性分别管理。

如假诺非数组和object类型,就径直回到。

固然是,就重返DynamicJson对象,那样当大家应用对象的天性,就能够调用TryGetMember方法

亚洲必赢官网 31

private static dynamic ToValue(XElement element)
{
     var type = (JsonType)Enum.Parse(typeof(JsonType), element.Attribute("type").Value);
     switch (type)
     {
         case JsonType.boolean:
             return (bool)element;
         case JsonType.number:
             return (double)element;
         case JsonType.@string:
             return (string)element;
         case JsonType.@object:
         case JsonType.array:
             return new DynamicJson(element, type);
         case JsonType.@null:
         default:
             return null;
    }
}

亚洲必赢官网 32

  1 那四个经过互为逆进程;

TryGetMember方法

上面是重写的TryGetMember方法

亚洲必赢官网 33

public override bool TryGetMember(GetMemberBinder binder, out object result)
{

    //根据访问的属性,在序列化的xml结构中寻找子element.
    var element = xml.Element(binder.Name);

    if (element == null)
    {
         result = null;
         return false;
    }

     result = ToValue(element);//如果存在该element, 就继续调用ToValue, 如果是普通类型,就能够返回具体的内容,如果是数组或object,就在返回一个DynamicJson对象。
     return true;
}

亚洲必赢官网 34

  贰 无论是类别化照旧反种类化,对象的景况音讯都与一段系列相呼应。

四,总结

DynamicJson的代码落成的功效多数,详细的DynamicJson的代码,能够因此Nuget获取。

经过持续DynamicObject类,落成了这几个多的成效类,

有针对Json的DynamicJson,还有针对xml的DynamicXml

接纳它们,减弱了不要求的类型定义,扩大了程序代码的八面后珑。

 

  上面我们就来看看哪些用C#言语进行Json和XML的连串化和反体系化。

  

   Json的类别化与反系列化

   ① 使用Newtonsoft.Json库

  首先我们先来看壹段代码:

 1 public void JsonDeserialize(string jsonString)
 2 {
 3     //Json的反序列化操作
 4     JObject jObject = JsonConvert.DeserializeObject(jsonString) as JObject;
 5     //清空listBox的结果
 6     listBoxResult.Items.Clear();
 7     //将解析得到的数据显示到listBox中
 8     listBoxResult.Items.Add("Name : " + jObject["name"] ?? "null");
 9     listBoxResult.Items.Add("Doing : " + jObject["doing"] ?? "null");
10     listBoxResult.Items.Add("HandleContent : " + jObject["handleContent"] ?? "null");
11     listBoxResult.Items.Add("DateTime : " + jObject["dateTime"] ?? "null");
12 }

  上面那一个法子的效果是,接收1段Json连串作为参数,在形成反序列化后,将兼具字段的值输出到ListBox中,上边是粗略的测试:

  亚洲必赢官网 35

  可以看到,仅仅用了一行代码,Json的剧情就根据字段全都被拿走到了,下边就来好好了结一下Newtonsoft.Json这些库的用法吧。

  Newtonsoft.Json是.NET平桃园2个尤其流行且高品质的Json种类化和反种类化开源库,提供了过多用来种类化和反体系化Json的类及方法,除了那些之外它还提供了用Linq操作Json、将Json转变到XML的效应,相较于守旧的用于种类化和反连串化的DataContractJsonSerializer类越来越好用,更便捷。本文只介绍其中比较根本的JsonConvert类和多少个常用的项目,越来越多内容咱们能够访问Json.NET的主页进行领悟。

  在介绍使用情势前,先来讲说Newtonsoft.Json.dll的引进。从VS201叁上马,ASP.NET的花色均自带了Newtonsoft.Json.dll,直接利用就可以,而此外版本可能别的连串只要未有的话,能够进入其官方主页,找到Github托管的地址进入并下载。上边演示引用该动态链接库的流程,

  一点击菜单栏的品种->增添引用,也许在消除方案能源管理器中找到项目,右键引用属性,点击增添引用,然后就能够张开该窗口。

  该窗口打开后,如若是第叁回增多Newtonsoft.Json.dll,请找到右下方的浏览开关,并精选Newtonsoft.Json.dll;若之前加多过该库,能够点击左侧的浏览菜单,并点击近来,左边会显示从前加多过的库的新闻,勾上需求的库,最终点击右下方的明确就可以。

  亚洲必赢官网 36

  

  增加了动态链接库还没完,要想行使当中的类和措施,须要引入相应的命名空间(倘诺你不想每定义1个目的就写1长串命名空间的话),本文主要使用的命名空间是Newtonsoft.Json以及Newtonsoft.Json.Linq

  亚洲必赢官网 37

  实现那两步之后就足以舒舒服服的发端解析我们伟大的Json了。

  Now,先来介绍本库比较主要的类,JsonConvert。JsonConvert是个相当实用的工具类,它提供了用于反类别化的DeserializeObject方法和DeserializeObject<T>方法,以及用于体系化的塞里alizeObject方法。由于这一个办法都以静态方法,因而没有需求创设JsonConvert对象,直接运用妥妥的(事实上JsonConvert是个静态类,根本非常小概被实例化)。

  在最开端演示的例子中,大家采纳了JsonConvert.DeserializeObject方法,这是最原始的Json反系列化方法,它接受string类型的参数并赶回object类型的指标。那么您也许会问到,它回到的靶子究竟是什么样品种???想要真正获得该目的的新闻,就必须将其强制转变到具体的派生类。那么,大家得以采取GetType方法来一探毕竟。

1 private void btnDeserialize_Click(object sender, EventArgs e)
2 {
3     //JsonDeserialize(textBox1.Text);
4     var secretObject = JsonConvert.DeserializeObject(textBox1.Text);
5     MessageBox.Show(secretObject.GetType().ToString());
6 }

   大家先在多个开关的点击事件对应的章程中分析输入的Json系列,由于大家还不鲜明JsonConvert.DeserializeObject方法重返什么目的,由此大家先用隐式类型对象去引用该办法重临的结果,然后调用其GetType方法,获取该对象所属类型的元数据,最后将目的的完整类型名彰显在对话框个中。奉行那段代码,你将会看出如下结果:

  亚洲必赢官网 38

  恐怕那时候在您的心扉又有三千0个草泥马呼啸而过,“What?还没搞清楚JsonConvert类的用法,怎么又跑出了三个竟然的类?”

  不过不妨,接下去笔者会对咱们的谜团进行逐项的分解。

   在Newtonsoft.Json.Linq命名空间中,定义了部分用于表示分化式的Json字符串的类,它们包涵JObject、JProperty、JToken、JArray、JValue、JContainer等等。

       
那么在这么些类在这之中,JToken充当着标杆的剧中人物,它是叁个抽象类,并达成了IJEnumerable<T>接口,而IJEnumerable<T>接口承继自IEnumerable<T>接口,那表示全体继续JToken的类都得以选拔foreach语句进行遍历,而接下去要介绍的这几个类,全都派生自JToken。其它,JToken还定义了First、Last、Parent、Root、Item、Previous、Next等遍历常常会用到的习性,因而在运用那么些类的时候,遍历、查找具体类等操作就显得万分的大致。说了如此多,是时候说说JObject了,那是个JToken的派生类,同时也是落成了JContainer接口、ICollection<T>、IKeyValuePair<T>,那表示JObject能够积攒多少个持续JToken类型的对象,同时也能够遍历它们,还能用键去获取相应的值,大概你还不亮堂这一个有何样用,那么大家先来打探一下Json的基本结构:

  一般的话,被大括号括起来的内容能够用作是2个完好无缺的(一个目的的),而被中括号括起来的剧情,能够当做是一组内容(一个数组),在一个千头万绪的Json结构中,大括号里面包车型大巴某些键的值能够在嵌一个大括号,代表该属性值为另1个Json对象,同理一个大括号中的有个别键的值能够嵌二当中括号,代表该属性值是2个数组,如

 1 //对于这种Json来说,可以看成是一个对象,里面包含了name、doing、handleContent和dateTime属性。
 2 {
 3     "name":".NET Coder",   
 4     "doing":"Deserialization",
 5     "handleContent":"Json",
 6     "dateTime":"2017-09-11 12:12:12"
 7 }
 8 
 9 //对于这种Json来说,可以看成是一个数组对象,里面包含了两个对象。
10 [
11   {
12     "name":".NET Coder",   
13     "doing":"Deserialization",
14     "handleContent":"Json",
15     "dateTime":"2017-09-11 12:12:12"
16   },
17   {
18     "name":"Java Coder",   
19     "doing":"Deserialization",
20     "handleContent":"Json",
21     "dateTime":"2017-09-22 21:21:21"
22   }
23 ]

  在上三个演示的例子中,大家用GetType方法去判定实现行反革命种类化之后,实际重临的类型是何等;那么接下去大家就将上边那二种不一样结构的Json种类放入程序中剖析,看看获得的靶子是还是不是都是JObject。

  亚洲必赢官网 39

      成功得到了JObject类型的对象。

  亚洲必赢官网 40

  这一次我们居然获得了JArray?!

  这下我们大概就了然了,JObject用于表示3个全体的Json对象组织,而JArray用于表示3个Json数组,当中会包涵三个或三个Json对象。

  在取得JObject对象之后,我们能够用属性名(键)去获取对应的属性值,也得以运用Next、Previous等质量去各类访问JObject的属性。

  而收获JArray对象之后,大家得以应用for大概foreach语句去遍历该目的内的成分,然后根据有个别属性名或Next、Previous等性情去做客当前成分有个别属性的属性值。

  那么JProperty和JValue类型又有何功能呢?

  大家得以来调解一下先后,并洞察JObject对象内的协会,

亚洲必赢官网 41

  如图大家在选择foreach循环遍历JObject内部的个性,能够见到,First属性指向了JObject的第二个属性,而它的品类是JProperty,因此大家能够领略,JProperty类用于描述1个Json对象中的某贰性子能,在其内部含有了三个KeyValuePair<string,
JToken>的积极分子变量,用于存款和储蓄该Json属性的键值对,而以此值,其实正是JValue类型的变量。

亚洲必赢官网 42

  

  那么到此处甘休,大家已经调控了DeserializeObject方法的用法了,不过很鲜明,那种方法解析Json数据实际上太麻烦了,大家须求把全体Json对象的习性2个个拿走到,然后本领收获个中的值,有未有更简要介绍的艺术吗?

  有!有!有!重要的政工说二回。

  下边该轮到DeserializeObject<T>方法出场了,那是个泛型方法,钦赐T的种类并传到Json字符串作为参数后,该方法会完毕反系列化并回到一个T类型的靶子。那么我们该钦赐什么类型给该办法吗?这么些类型必要依靠Json数据的等级次序关系自行设计,假诺大家是第三遍采纳,不清楚该怎么设计,那么大家来让VS帮我们规划,上边给大家介绍四个奇妙的成效,VS的电动建类功用:

  依旧那段Json系列,假诺大家必要将其反类别化,今后却不明白怎么规划类,那么大家得以先复制那段Json种类,

1 {
2     "name":".NET Coder",   
3     "doing":"Serialization",
4     "handleContent":"Json",
5     "dateTime":"2017-09-11 12:12:12"
6 }

  张开VS,在菜单栏找到编辑->选取性粘贴,点击将Json粘贴为类,就相会世下边包车型客车结果,

亚洲必赢官网 43

亚洲必赢官网 44

  原本空白的地方,突然冒出了多个类的概念(即便Json有五个层级,VS会帮我们调换多少个类),这些类清晰的反映了这段Json的协会,此时我们只须要将这一个自动生成的类,用到格局里就好了:

  亚洲必赢官网 45

  亚洲必赢官网 46 

  我们改写了JsonDeserialize方法,并动用了由VS生成的类,能够见到大家无需再依附属性名去获得属性值了,也不用再担忧忘记有何性质只怕属性名写错,只需求在对象前边加上一些,该对象的兼具属性都晤面世在增选列表中。是还是不是突然感到日前壹亮,1身轻易了吗?但实质上这么些做法隐藏了一小点小标题,因为VS是基于Json原来的个性名来定义属性的,那将必要Json的属性名遵从C#的标记符定义规则,然后实际,在Json中或然会现身不符合C#标记符定义规范的属性名,那并从未错,如上边那段Json:

1 {
2     "name":"money",   
3     "price":"66.6",
4     "int":"64",
5     "a-b":"c-d",
6     "@#$":"sdfsdf"
7 }

亚洲必赢官网 47

  能够见见,固然VS会用_去顶替不合规的字符串并依照标准生成属性名,不过那样子的属性名已经失却了它的意思,我们无能为力获知那特性情表明了哪些含义,为了减轻那几个主题材料,大家得以使用C#的注释来给该类的质量制定多少协定

  亚洲必赢官网 48

 

  
DataContract和DataMember证明来自于命名空间System.Runtime.Serialization,那个命名空间所在的动态链接库项目暗中认可是向来不引进的,须要手动引进,大家只须要坚守地点引进Newtonsoft.Json.dll的措施引进就好,不过要求注意的是,System.Runtime.Serialization所在的动态链接库在VS程序聚焦是提供了的,大家只供给在加上引用分界面,点击程序集,并在右边的列表找到System.Runtime.Serialization并勾选,然后点击右下角的规定开关就可以。

  实现这几个手续之后我们就足以退换Json的实体类,为其增加数据协定。什么是数额协定吗,即数据的发送方和接收方无需使用一样的类别,只要求根据数据协定就可以。为了使该类能够加多数据协定,要求在类名上方增添[DataContract]评释,表达该类的质量使用了数据协定,并且同意将该类实行系列化,设若不加那么些申明,就无法应用[DataMember]注解了。添加[DataContract]表明后,我们就能够在相应的性质上增多[DataMember]疏解,该声明有伍个参数:

参数名 作用
Name 标识该属性对应的Json属性名
Order 标识该属性序列化和反序列化的顺序
IsRequired 标识该属性在读取或反序列化时是否必须存在,类型为bool
EmitDefaultValue 标识在序列化的过程中是否使用该属性的默认值来序列化

 

  上海体育地方大家应用了Name参数来设置各样属性对应的Json属性名,从而进步了此类在程序中的可读性,同时又不会对种类化和反体系化的长河爆发麻烦。上面再改写一下JsonDeserialize方法呢:

  亚洲必赢官网 49

   亚洲必赢官网 50

  测试成功!!!

   别的再补偿3个小知识,当大家必要反体系化大多简练的Json时,为了制止成立过多的实体类,大家能够运用dynamic动态类型来代替自定义的实体类,在那边大家改写上述例子,使用dynamic类型来贯彻相应成效:

  亚洲必赢官网 51

 

  在这些事例中,作者从不定义新的类,而是采纳了动态类型,那体系型的目的有3个风味:运转时检查。在利用那种对象的时候我们要专注,无论是使用它的性质,照旧调用它的法子,编写翻译器都不会对其举办编写翻译时检查,也便是说大家务必确定保障属性名或许措施名尚未写错,不然会油不过生表明式为空也许吸引那多少个的风貌。

  亚洲必赢官网 52

   亚洲必赢官网 53

  调用不存在的本性再次来到Null。

 

  亚洲必赢官网 54

  调用不存在的方法引发这些。

 

  亚洲必赢官网 55

  在尚未不当的情状下,成功运营!

  

  到此地反种类化的介绍算是告壹段落了,接下去大家讲讲使用JsonConvert.SerializeObject方法成功系列化操作。

  前边那么多操作的目的是为精晓析Json字符串,让我们能便于的收获当中的音讯,但是只要大家不是音讯的接收方而是发送方呢,大家要怎么布局Json字符串?分明不大概用字符串拼接的秘技,效能低下,难以排错。因而后天大家就要用一行代码来完毕那件业务。

  

  亚洲必赢官网 56

 

  没有错,就唯有一行代码!!!

 

  亚洲必赢官网 57

  亚洲必赢官网 58

  看吗,是或不是单排代码就让二个毋庸置疑的目标须臾间改成了一串Json了吧!!!

  

  ② 使用DataContractJsonSerializer类

  其实自身并不想讲明这些类,第1应用进程非凡麻烦,第1频率低下,实际专门的学业中也不会用它,不过从学习的角度我们照旧要询问一下以此类的留存,并且那些类种类化和反体系化Json的长河和XML的体系化和反体系化很相似,由此照旧有不可或缺让大家通晓一下。

  在此不多说其余废话,间接上代码:

  DataContractJsonSerializer序列化

 1 public void OldJsonSerialize()
 2 {
 3     DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(HandleObject));
 4     //创建实体类
 5     HandleObject jObject = new HandleObject() {
 6         Name = ".NET Coder",
 7         Doing = "Serialization",
 8         HandleContent = "Json",
 9         DateTime = DateTime.Now.ToString("yyyy-MM-ss")
10     };
11     //创建内存流,用于存储序列化后得到的内容
12     MemoryStream ms = new MemoryStream();
13     //将对象序列化后存入内存流
14     serializer.WriteObject(ms, jObject);
15     //将内存流的内容转换成字符串并输出到文本框
16     textBox1.Text = Encoding.UTF8.GetString(ms.ToArray());
17 }

亚洲必赢官网 59

 

  DataContractJsonSerializer反系列化

 1 public void OldJsonDeserialize()
 2 {
 3     DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(HandleObject));
 4     //将Json字符串转换成字节数组
 5     byte[] content = Encoding.UTF8.GetBytes(textBox1.Text);
 6     //用字节数组初始化一个内存流对象
 7     MemoryStream ms = new MemoryStream(content);
 8     //完成反序列化操作
 9     HandleObject handleObject = serializer.ReadObject(ms) as HandleObject;
10     //将解析得到的数据显示到listBox中
11     listBoxResult.Items.Add("Name : " + handleObject.Name ?? "null");
12     listBoxResult.Items.Add("Doing : " + handleObject.Doing ?? "null");
13     listBoxResult.Items.Add("HandleContent : " + handleObject.HandleContent ?? "null");
14     listBoxResult.Items.Add("DateTime : " + (handleObject.DateTime.ToString() ?? "null"));
15 }

亚洲必赢官网 60

 

  DataContractJsonSerializer类和JsonConvert类最大的差异就在于,DataContractJsonSerializer类将操作流的底细揭穿了出来,须求由用户自动完毕,相比较JsonConvert直接利用字符串要麻烦不少。

网站地图xml地图