也談C#之Json,從Json字符串到類代碼,
閱讀目錄
json轉類對象
自從.net 4.0開始,微軟提供了一整套的針對json進行處理的方案。其中,就有如何把json字符串轉化成C#類對象,其實這段代碼很多人都清楚,大家也都認識,我就不多說,先貼代碼。
1、添加引用 System.Web.Extensions

2、測試一下代碼
1 static class Program
2 {
3 /// <summary>
4 /// 程序的主入口點。
5 /// </summary>
6 static void Main()
7 {
8 string jsonStr = "{\"name\":\"supperlitt\",\"age\":25,\"likes\":[\"C#\",\"asp.net\"]}";
9 JavaScriptSerializer js = new JavaScriptSerializer();
10 var model = js.Deserialize<TestModel>(jsonStr);
11
12 Console.WriteLine(model.name);
13 Console.WriteLine(model.age);
14 Console.WriteLine(string.Join(",", model.likes));
15
16 Console.ReadLine();
17 }
18
19 public class TestModel
20 {
21 public string name { get; set; }
22
23 public int age { get; set; }
24
25 public List<string> likes { get; set; }
26 }
27 }
輸出內容:

逆思考
由於代碼中,經常會遇到需要處理json字符串(抓包比較頻繁)。每次遇到json字符串,大多需要解析,又要進行重復勞動,又需要定義一個C#對象類,有沒有一個比較好的辦法解決呢,不用每次都去寫代碼。自動生成多好。。。
於是LZ思前,向後,想到了以前用過的一個微軟的類庫,應該是微軟的一個Com庫。

從json字符串自動生成C#類
1、試著百度了一下,也嘗試了幾個可以使用的類。於是找到了
如下的代碼,能夠解析一個json字符串,成為一個C#的對象。
這裡引用了,Microsoft.JScript.dll 類庫。
1 Microsoft.JScript.Vsa.VsaEngine ve = Microsoft.JScript.Vsa.VsaEngine.CreateEngine();
2 var m = Microsoft.JScript.Eval.JScriptEvaluate("(" + jsonStr + ")", ve);
2、發現這個m對象,其實是一個JSObject對象,內部也可以繼續進行細分,於是測試了種種,稍後會上源碼。先看測試效果吧。
我們隨便在web上面找了一個json字符串來進行處理。當然json要稍稍復雜一點。

ps:代碼如下

![]()
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using Microsoft.JScript;
6
7 namespace Common
8 {
9 /// <summary>
10 /// Json字符串zhuanh
11 /// </summary>
12 public class JsonHelper : IHelper
13 {
14 /// <summary>
15 /// 是否添加get set
16 /// </summary>
17 private bool isAddGetSet = false;
18
19 /// <summary>
20 /// 數據集合,臨時
21 /// </summary>
22 private List<AutoClass> dataList = new List<AutoClass>();
23
24 public JsonHelper()
25 {
26 }
27
28 public JsonHelper(bool isAddGetSet)
29 {
30 this.isAddGetSet = isAddGetSet;
31 }
32
33 /// <summary>
34 /// 獲取類的字符串形式
35 /// </summary>
36 /// <param name="jsonStr"></param>
37 /// <returns></returns>
38 public string GetClassString(string jsonStr)
39 {
40 Microsoft.JScript.Vsa.VsaEngine ve = Microsoft.JScript.Vsa.VsaEngine.CreateEngine();
41 var m = Microsoft.JScript.Eval.JScriptEvaluate("(" + jsonStr + ")", ve);
42
43 int index = 0;
44 var result = GetDicType((JSObject)m, ref index);
45
46 StringBuilder content = new StringBuilder();
47 foreach (var item in dataList)
48 {
49 content.AppendFormat("\tpublic class {0}\r\n", item.CLassName);
50 content.AppendLine("\t{");
51 foreach (var model in item.Dic)
52 {
53 if (isAddGetSet)
54 {
55 content.AppendFormat("\t\tpublic {0} {1}", model.Value, model.Key);
56 content.Append(" { get; set; }\r\n");
57 }
58 else
59 {
60 content.AppendFormat("\t\tpublic {0} {1};\r\n", model.Value, model.Key);
61 }
62
63 content.AppendLine();
64 }
65
66 content.AppendLine("\t}");
67 content.AppendLine();
68 }
69
70 return content.ToString();
71 }
72
73 /// <summary>
74 /// 獲取類型的字符串表示
75 /// </summary>
76 /// <param name="type"></param>
77 /// <returns></returns>
78 private string GetTypeString(Type type)
79 {
80 if (type == typeof(int))
81 {
82 return "int";
83 }
84 else if (type == typeof(bool))
85 {
86 return "bool";
87 }
88 else if (type == typeof(Int64))
89 {
90 return "long";
91 }
92 else if (type == typeof(string))
93 {
94 return "string";
95 }
96 else if (type == typeof(List<string>))
97 {
98 return "List<string>";
99 }
100 else if (type == typeof(List<int>))
101 {
102 return "List<int>";
103 }
104 else
105 {
106 return "string";
107 }
108 }
109
110 /// <summary>
111 /// 獲取字典類型
112 /// </summary>
113 /// <returns></returns>
114 private string GetDicType(JSObject jsObj, ref int index)
115 {
116 AutoClass classInfo = new AutoClass();
117
118 var model = ((Microsoft.JScript.JSObject)(jsObj)).GetMembers(System.Reflection.BindingFlags.GetField);
119 foreach (Microsoft.JScript.JSField item in model)
120 {
121 string name = item.Name;
122 Type type = item.GetValue(item).GetType();
123 if (type == typeof(ArrayObject))
124 {
125 // 集合
126 string typeName = GetDicListType((ArrayObject)item.GetValue(item), ref index);
127 if (!string.IsNullOrEmpty(typeName))
128 {
129 classInfo.Dic.Add(name, typeName);
130 }
131 }
132 else if (type == typeof(JSObject))
133 {
134 // 單個對象
135 string typeName = GetDicType((JSObject)item.GetValue(item), ref index);
136 if (!string.IsNullOrEmpty(typeName))
137 {
138 classInfo.Dic.Add(name, typeName);
139 }
140 }
141 else
142 {
143 classInfo.Dic.Add(name, GetTypeString(type));
144 }
145 }
146
147 index++;
148 classInfo.CLassName = "Class" + index;
149 dataList.Add(classInfo);
150 return classInfo.CLassName;
151 }
152
153 /// <summary>
154 /// 讀取集合類型
155 /// </summary>
156 /// <param name="jsArray"></param>
157 /// <param name="index"></param>
158 /// <returns></returns>
159 private string GetDicListType(ArrayObject jsArray, ref int index)
160 {
161 string name = string.Empty;
162 if ((int)jsArray.length > 0)
163 {
164 var item = jsArray[0];
165 var type = item.GetType();
166 if (type == typeof(JSObject))
167 {
168 name = "List<" + GetDicType((JSObject)item, ref index) + ">";
169 }
170 else
171 {
172 name = "List<" + GetTypeString(type) + ">";
173 }
174 }
175
176 return name;
177 }
178 }
179
180 public class AutoClass
181 {
182 public string CLassName { get; set; }
183
184 private Dictionary<string, string> dic = new Dictionary<string, string>();
185
186 public Dictionary<string, string> Dic
187 {
188 get
189 {
190 return this.dic;
191 }
192 set
193 {
194 this.dic = value;
195 }
196 }
197 }
198 }
View Code
調用方式:
1 JsonHelper helper = new JsonHelper(true);
2 try
3 {
4 this.txtOutPut.Text = helper.GetClassString("json字符串");
5 }
6 catch
7 {
8 this.txtOutPut.Text = "輸入內容不符合規范...";
9 }
最後如果dudu允許的話,我再附上一個測試地址吧:http://www.51debug.com/tool/JsonToCharpCode.aspx
博客也寫了幾次了,不過每次都寫得比較濫,看著不舒服,這次用心寫了一下,歡迎大家拍磚或提供更好的建議。