<b>閱讀目錄</b>
<a href="http://www.cnblogs.com/asxinyu/p/dotnet_Opensource_project_json_generator.html#_label0">1.複雜的JSON啥樣子?</a>
<a href="http://www.cnblogs.com/asxinyu/p/dotnet_Opensource_project_json_generator.html#_label1">2.使用JSON C# Class Generator介紹和使用</a>
<a href="http://www.cnblogs.com/asxinyu/p/dotnet_Opensource_project_json_generator.html#_label2">3.就這麼完了?No,沒那麼簡單</a>
<a href="http://www.cnblogs.com/asxinyu/p/dotnet_Opensource_project_json_generator.html#_label3">4.資源</a>
看看下面這個圖,文本檔案都是12K,嵌套多層,說實話,我是沒耐心看下去的。是以找了個工具結構化了一下。看圖對比:

使用過程很簡單,如下圖官網的截圖所示:輸入命名空間,主類名,生成的cs檔案目錄,以及類型即可。同時右邊還有可見性,和一些簡單的配置,簡單易懂。
下面看看我們示範的這個JSON的使用,是在網絡找到的一段示範JSON代碼,我自己用到的實際資料有些比這還複雜。首先我們把JSON複制到JSON C# Class Generator中,設定相關參數,如下圖所示,生成檔案後,複制到項目中,下面我們可以寫測試代碼,看看起解析的格式:
說明一下,我們JSON反序列需要用到Newtonsoft元件,這個相信大部分都肯定比我熟悉。将生成的檔案複制到項目中,并添加的引用,如下代碼就反序列化OK了。是不是So Easy?
1
2
3
4
<code>//擷取jsonzifc </code>
<code>var</code> <code>json = File.ReadAllText(</code><code>"複雜JSON例子.txt"</code><code>);</code>
<code>//使用Newtonsoft反序列化</code>
<code>var</code> <code>model = JsonConvert.DeserializeObject<TestJson>(json);</code>
其實這個套路大部分人也都懂,但我知道的也有一些線上解析工具,但貌似遇到特别複雜的,不好整,這個工具是我見過的裡面比較簡單易用。看看解析的資料,結構化後,非常清晰,自己想要那個資料,自己去屬性依次擷取就好了。
工具能解決的問題一般不是全部,能解決8成就很不錯了,雖然這個工具剛開始就解決了很多問題,但随着JSON的複雜化,也碰到了一些坑,看看如何填坑。現在已經是填坑專業戶了。
為什麼在對于複雜的類型我選擇使用嵌套類,原因很簡單,結構更清晰,否則生成的cs檔案裡面一堆類,都搞不清楚那個是最外面的,對這種需求,适當的代碼備援就無所謂了,我需要的是快速的拿到自己想要的資料。何況是自動生成的。當然對于簡單的類型,不使用嵌套類也是可以的,看個人習慣吧。
雖然比較奇葩,但的确是遇到了,擷取的JSON字元串裡面的字段名稱為數字,怎麼破?鬼知道人家這麼拼出來的,反正是為了采集,還得有解藥才行。既然原始的是數字,那就把原始的給改了,我們把屬性是數字的地方,都給加一個預設值,然後生成實體類,不就可以了,不過想在這麼一堆亂七八糟的東西裡面把所有的數字屬性加個預設值,也不容易啊,還好有萬能的正規表達式。
我們寫一個簡單的正規表達式比對方法,把數字屬性統一替換為前面加個預設的字母A,代碼如下:
5
6
7
8
9
10
11
12
<code>public</code> <code>static</code> <code>string</code> <code>GetNewJson(String json)</code>
<code>{</code>
<code> </code><code>Regex reg = </code><code>new</code> <code>Regex(</code><code>"\"([^\"]d*)\":"</code><code>); </code><code>//注意裡面的引号 要用雙引号表示,而不是用反斜杠</code>
<code> </code><code>MatchEvaluator matchEval = </code><code>new</code> <code>MatchEvaluator(ReplaceStar);</code>
<code> </code><code>return</code> <code>reg.Replace(json, matchEval);</code>
<code>}</code>
<code>static</code> <code>string</code> <code>ReplaceStar(Match match)</code>
<code> </code><code>string</code> <code>str = match.Value.Replace(</code><code>"\""</code><code>, </code><code>""</code><code>).Replace(</code><code>":"</code><code>, </code><code>""</code><code>);</code>
<code> </code><code>return</code> <code>"\"A"</code> <code>+ str + </code><code>"\":"</code><code>;</code>
很多時候某個屬性下面有多個相同結構的對象,但是會根據名稱解析為不同的類,結構基本一直,在擷取對象資料的時候,又不是數組對象,循環還不好搞,那怎麼破?
手動建一個中間類,結構和他們一樣,使用TinyMaper,這裡有文章介紹,将這些類型預設都映射到這個中間類中,然後其他各個相同結構對象的解析隻需要寫一份代碼就OK了。看看下面的方法:
13
14
15
16
<code>public</code> <code>class</code> <code>LineRato</code>
<code>{ </code>
<code> </code><code>public</code> <code>string</code> <code>LgMailNo;</code>
<code> </code><code>public</code> <code>string</code> <code>CreateTime; </code>
<code> </code><code>public</code> <code>string</code> <code>EventTime; </code>
<code> </code><code>public</code> <code>string</code> <code>EventAddress; </code>
<code> </code><code>public</code> <code>string</code> <code>NodeType; </code>
<code> </code><code>public</code> <code>string</code> <code>Timeout;</code>
<code> </code><code>/// <summary>将其他結構相同的類轉換為中間類</summary></code>
<code> </code><code>public</code> <code>static</code> <code>LineRato GetLine<T>(T model)</code>
<code> </code><code>{</code>
<code> </code><code>TinyMapper.Bind<T, LineRato>();</code>
<code> </code><code>return</code> <code>TinyMapper.Map<LineRato>(model);</code>
<code> </code><code>}</code>
某些時候我們在第一次擷取JSON值的時候,由于某些值是空的,導緻實際的JSON值裡面沒包括該字段,是以在生成的時候實體類裡面肯定沒有這個字段,而實際多次後發現某些情況下該值又不為空,會導緻解析失敗,這個時候怎麼破?
沒辦法破了,為了省事,看看是那裡缺少字段,手動加上吧,就一行代碼的事情。
總之,在解決了80%問題後,剩下的方法比問題多多了,大家各顯神通吧。這裡隻是吧自己的解決過程寫下來,最快的解決問題,OK!其他費腦細胞的事情還是給有精力的人!
本文轉自葉小钗 h資料之巅部落格園部落格,原文連結:http://www.cnblogs.com/asxinyu/p/dotnet_Opensource_project_json_generator.html,如需轉載請自行聯系原作者