去年,我在一篇文章用原始方法解析复杂字符串,json一定要用JsonMapper么?中介绍了简单的JSON解析的问题,那种方法在当时的环境是非常方便的,因为不需要生成实体类,结构很容易解析。但随着业务的变化,也会碰到超级变态的JSON,如果还按照以前的思路,会把人搞抽风掉,一旦结构变化,又要重来。所以今天给大家介绍一个简单的方法,轻轻松松搞定超级变态的JSON,虽然需要生成实体类。它就是开源的:JSON C# Class Generator组件。

.NET开源目录:【目录】本博客其他.NET开源项目文章目录

本文原文地址:http://www.cnblogs.com/asxinyu/p/dotnet_Opensource_project_json_generator.html

1.复杂的JSON啥样子?

看看下面这个图,文本文件都是12K,嵌套多层,说实话,我是没耐心看下去的。所以找了个工具结构化了一下。看图对比:

2.使用JSON C# Class Generator介绍和使用

JSON C# Class Generator是一个从JSON文本中生成C#内的应用程序。项目地址:https://jsonclassgenerator.codeplex.com/ ,目前支持数组,对象,整形,单精度,布尔,字符串和空值符类型。

使用过程很简单,如下图官网的截图所示:输入命名空间,主类名,生成的cs文件目录,以及类型即可。同时右边还有可见性,和一些简单的配置,简单易懂。

  

  下面看看我们演示的这个JSON的使用,是在网络找到的一段演示JSON代码,我自己用到的实际数据有些比这还复杂。首先我们把JSON复制到JSON C# Class Generator中,设置相关参数,如下图所示,生成文件后,复制到项目中,下面我们可以写测试代码,看看起解析的格式:

说明一下,我们JSON反序列需要用到Newtonsoft组件,这个相信大部分都肯定比我熟悉。将生成的文件复制到项目中,并添加的引用,如下代码就反序列化OK了。是不是So Easy?

//获取jsonzifc 
var json = File.ReadAllText("复杂JSON例子.txt");
//使用Newtonsoft反序列化
var model = JsonConvert.DeserializeObject<TestJson>(json);

其实这个套路大部分人也都懂,但我知道的也有一些在线解析工具,但貌似遇到特别复杂的,不好整,这个工具是我见过的里面比较简单易用。看看解析的数据,结构化后,非常清晰,自己想要那个数据,自己去属性依次获取就好了。

3.就这么完了?No,没那么简单

工具能解决的问题一般不是全部,能解决8成就很不错了,虽然这个工具刚开始就解决了很多问题,但随着JSON的复杂化,也碰到了一些坑,看看如何填坑。现在已经是填坑专业户了。

3.1 为什么要使用嵌套类(nested classes)

为什么在对于复杂的类型我选择使用嵌套类,原因很简单,结构更清晰,否则生成的cs文件里面一堆类,都搞不清楚那个是最外面的,对这种需求,适当的代码冗余就无所谓了,我需要的是快速的拿到自己想要的数据。何况是自动生成的。当然对于简单的类型,不使用嵌套类也是可以的,看个人习惯吧。

3.2 解析会碰到类型名称为数字的字段

虽然比较奇葩,但的确是遇到了,获取的JSON字符串里面的字段名称为数字,怎么破?鬼知道人家这么拼出来的,反正是为了采集,还得有解药才行。既然原始的是数字,那就把原始的给改了,我们把属性是数字的地方,都给加一个默认值,然后生成实体类,不就可以了,不过想在这么一堆乱七八糟的东西里面把所有的数字属性加个默认值,也不容易啊,还好有万能的正则表达式。

我们写一个简单的正则表达式匹配方法,把数字属性统一替换为前面加个默认的字母A,代码如下:

public static string GetNewJson(String json)
{
Regex reg = new Regex("\"([^\"]d*)\":"); //注意里面的引号 要用双引号表示,而不是用反斜杠
MatchEvaluator matchEval = new MatchEvaluator(ReplaceStar);
return reg.Replace(json, matchEval);
} static string ReplaceStar(Match match)
{
string str = match.Value.Replace("\"", "").Replace(":", "");
return "\"A" + str + "\":";
}

3.3 相同结构的,但解析为不同的类名

很多时候某个属性下面有多个相同结构的对象,但是会根据名称解析为不同的类,结构基本一直,在获取对象数据的时候,又不是数组对象,循环还不好搞,那怎么破?

手动建一个中间类,结构和他们一样,使用TinyMaper,这里有文章介绍,将这些类型默认都映射到这个中间类中,然后其他各个相同结构对象的解析只需要写一份代码就OK了。看看下面的方法:

public class LineRato
{  
public string LgMailNo;
public string CreateTime;        
public string EventTime;     
public string EventAddress;     
public string NodeType;     
public string Timeout; /// <summary>将其他结构相同的类转换为中间类</summary>
public static LineRato GetLine<T>(T model)
{
TinyMapper.Bind<T, LineRato>();
return TinyMapper.Map<LineRato>(model);
}
}

3.4 空值导致实体类字段缺失

某些时候我们在第一次获取JSON值的时候,由于某些值是空的,导致实际的JSON值里面没包括该字段,所以在生成的时候实体类里面肯定没有这个字段,而实际多次后发现某些情况下该值又不为空,会导致解析失败,这个时候怎么破?

没办法破了,为了省事,看看是那里缺少字段,手动加上吧,就一行代码的事情。

  总之,在解决了80%问题后,剩下的方法比问题多多了,大家各显神通吧。这里只是吧自己的解决过程写下来,最快的解决问题,OK!其他费脑细胞的事情还是给有精力的人!  

4.资源

本文代码:JsonClassTest.rar

项目地址:https://jsonclassgenerator.codeplex.com/

.NET平台开源项目速览(18)C#平台JSON实体类生成器JSON C# Class Generator的更多相关文章

  1. .NET平台开源项目速览(7)关于NoSQL数据库LiteDB的分页查询解决过程

    在文章:这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧!(第二辑) 与 .NET平台开源项目速览(3)小巧轻量级NoSQL文件数据库LiteDB中,介绍了LiteDB的基本使用情况以及部 ...

  2. .NET平台开源项目速览(17)FluentConsole让你的控制台酷起来

    从该系列的第一篇文章 .NET平台开源项目速览(1)SharpConfig配置文件读写组件 开始,不知不觉已经到第17篇了.每一次我们都是介绍一个小巧甚至微不足道的.NET平台的开源软件,或者学习,或 ...

  3. .NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验

    不知不觉,“.NET平台开源项目速览“系列文章已经15篇了,每一篇都非常受欢迎,可能技术水平不高,但足够入门了.虽然工作很忙,但还是会抽空把自己知道的,已经平时遇到的好的开源项目分享出来.今天就给大家 ...

  4. .NET平台开源项目速览(13)机器学习组件Accord.NET框架功能介绍

    Accord.NET Framework是在AForge.NET项目的基础上封装和进一步开发而来.因为AForge.NET更注重与一些底层和广度,而Accord.NET Framework更注重与机器 ...

  5. .NET平台开源项目速览(1)SharpConfig配置文件读写组件

    在.NET平台日常开发中,读取配置文件是一个很常见的需求.以前都是使用System.Configuration.ConfigurationSettings来操作,这个说实话,搞起来比较费劲.不知道大家 ...

  6. .NET平台开源项目速览(12)哈希算法集合类库HashLib

    .NET的System.Security.Cryptography命名空间本身是提供加密服务,散列函数,对称与非对称加密算法等功能.实际上,大部分情况下已经满足了需求,而且.NET实现的都是目前国际上 ...

  7. .NET平台开源项目速览(11)KwCombinatorics排列组合使用案例(1)

    今年上半年,我在KwCombinatorics系列文章中,重点介绍了KwCombinatorics组件的使用情况,其实这个组件我5年前就开始用了,非常方便,麻雀虽小五脏俱全.所以一直非常喜欢,才写了几 ...

  8. .NET平台开源项目速览(10)FluentValidation验证组件深入使用(二)

    在上一篇文章:.NET平台开源项目速览(6)FluentValidation验证组件介绍与入门(一) 中,给大家初步介绍了一下FluentValidation验证组件的使用情况.文章从构建间的验证器开 ...

  9. .NET平台开源项目速览(9)软件序列号生成组件SoftwareProtector介绍与使用

    在文章:这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧!(第二辑)中,给大家初步介绍了一下Software Protector序列号生成组件.今天就通过一篇简单的文章来预览一下其强大的功 ...

随机推荐

  1. Be Better:遇见更好的自己-2016年记

    其实并不能找到好的词语来形容过去的一年,感觉就如此平淡的过了!没有了毕业的稚气,看事情淡了,少了一丝浮躁,多了一分认真.2016也许就是那句话-多读书,多看报,少吃零食多睡觉,而我更愿意说--Be B ...

  2. 【探索】无形验证码 —— PoW 算力验证

    先来思考一个问题:如何写一个能消耗对方时间的程序? 消耗时间还不简单,休眠一下就可以了: Sleep(1000) 这确实消耗了时间,但并没有消耗 CPU.如果对方开了变速齿轮,这瞬间就能完成. 不过要 ...

  3. Android 自定义 attr

    好纠结,弄了一个下午老是报错如是总结一下安卓自定视图和自定义属性. (一)自定义属性 在Values文件下建立一个attrs.xml文件,attr的format可以参考:http://www.cnbl ...

  4. Gradle 实现 Android 多渠道定制化打包

    Gradle 实现 Android 多渠道定制化打包 版权声明:本文为博主原创文章,未经博主允许不得转载. 最近在项目中遇到需要实现 Apk 多渠道.定制化打包, Google .百度查找了一些资料, ...

  5. 讓TQ2440也用上設備樹(1)

    作者:彭東林 郵箱:pengdonglin137@163.com QQ:405728433 開發板 TQ2440 + 64MB 內存 + 256MB Nand 軟件 Linux: Linux-4.9 ...

  6. golang struct扩展函数参数命名警告

    今天在使用VSCode编写golang代码时,定义一个struct,扩展几个方法,如下: package storage import ( "fmt" "github.c ...

  7. Java之多态(二)

    package test05;import test06.Car1;public class DuoTai_Test02 { /**多个对象,一个形态 * Tiger.Lion.Snake → Ani ...

  8. 2DToolkit官方文档中文版打地鼠教程(一):初始设置

    这是2DToolkit官方文档中 Whack a Mole 打地鼠教程的译文,为了减少文中过多重复操作的翻译,以及一些无必要的句子,这里我假设你有Unity的基础知识(例如了解如何新建Sprite等) ...

  9. jexus5.8.2 linux x64专业版 配置https

    一.环境 1.jexus版本:Jexus/5.8.2.8 Linux专业版 内置mono版本:Mono/4.6.2.7 2.操作系统:centOs7 jexus独立版由于是免安装版并且内置mono,所 ...

  10. useful commands for docker beginner

    You may want to add my wechat public account or add my technical blog's RSS feed This list is meant ...