JsonHelper.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Text.Json;
  6. using System.Threading.Tasks;
  7. namespace Ropin.Inspection.Common.Helper
  8. {
  9. public class JsonHelper
  10. {
  11. /// <summary>
  12. /// 转换对象为JSON格式数据
  13. /// </summary>
  14. /// <typeparam name="T">类</typeparam>
  15. /// <param name="obj">对象</param>
  16. /// <returns>字符格式的JSON数据</returns>
  17. public static string GetJSON<T>(object obj)
  18. {
  19. string result = String.Empty;
  20. try
  21. {
  22. JsonSerializer.Serialize("");
  23. System.Runtime.Serialization.Json.DataContractJsonSerializer serializer =
  24. new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T));
  25. using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
  26. {
  27. serializer.WriteObject(ms, obj);
  28. result = System.Text.Encoding.UTF8.GetString(ms.ToArray());
  29. }
  30. }
  31. catch (Exception)
  32. {
  33. throw;
  34. }
  35. return result;
  36. }
  37. /// <summary>
  38. /// 转换List<T>的数据为JSON格式
  39. /// </summary>
  40. /// <typeparam name="T">类</typeparam>
  41. /// <param name="vals">列表值</param>
  42. /// <returns>JSON格式数据</returns>
  43. public string JSON<T>(List<T> vals)
  44. {
  45. System.Text.StringBuilder st = new System.Text.StringBuilder();
  46. try
  47. {
  48. System.Runtime.Serialization.Json.DataContractJsonSerializer s = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T));
  49. foreach (T city in vals)
  50. {
  51. using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
  52. {
  53. s.WriteObject(ms, city);
  54. st.Append(System.Text.Encoding.UTF8.GetString(ms.ToArray()));
  55. }
  56. }
  57. }
  58. catch (Exception)
  59. {
  60. }
  61. return st.ToString();
  62. }
  63. /// <summary>
  64. /// JSON格式字符转换为T类型的对象
  65. /// </summary>
  66. /// <typeparam name="T"></typeparam>
  67. /// <param name="jsonStr"></param>
  68. /// <returns></returns>
  69. public static T ParseFormByJson<T>(string jsonStr)
  70. {
  71. T obj = Activator.CreateInstance<T>();
  72. using (System.IO.MemoryStream ms =
  73. new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(jsonStr)))
  74. {
  75. System.Runtime.Serialization.Json.DataContractJsonSerializer serializer =
  76. new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T));
  77. return (T)serializer.ReadObject(ms);
  78. }
  79. }
  80. public string JSON1<SendData>(List<SendData> vals)
  81. {
  82. System.Text.StringBuilder st = new System.Text.StringBuilder();
  83. try
  84. {
  85. System.Runtime.Serialization.Json.DataContractJsonSerializer s = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(SendData));
  86. foreach (SendData city in vals)
  87. {
  88. using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
  89. {
  90. s.WriteObject(ms, city);
  91. st.Append(System.Text.Encoding.UTF8.GetString(ms.ToArray()));
  92. }
  93. }
  94. }
  95. catch (Exception)
  96. {
  97. }
  98. return st.ToString();
  99. }
  100. private static bool IsJsonStart(ref string json)
  101. {
  102. if (!string.IsNullOrEmpty(json))
  103. {
  104. json = json.Trim('\r', '\n', ' ');
  105. if (json.Length > 1)
  106. {
  107. char s = json[0];
  108. char e = json[json.Length - 1];
  109. return (s == '{' && e == '}') || (s == '[' && e == ']');
  110. }
  111. }
  112. return false;
  113. }
  114. public static bool IsJson(string json)
  115. {
  116. int errIndex;
  117. return IsJson(json, out errIndex);
  118. }
  119. public static bool IsJson(string json, out int errIndex)
  120. {
  121. errIndex = 0;
  122. if (IsJsonStart(ref json))
  123. {
  124. CharState cs = new CharState();
  125. char c;
  126. for (int i = 0; i < json.Length; i++)
  127. {
  128. c = json[i];
  129. if (SetCharState(c, ref cs) && cs.childrenStart)//设置关键符号状态。
  130. {
  131. string item = json.Substring(i);
  132. int err;
  133. int length = GetValueLength(item, true, out err);
  134. cs.childrenStart = false;
  135. if (err > 0)
  136. {
  137. errIndex = i + err;
  138. return false;
  139. }
  140. i = i + length - 1;
  141. }
  142. if (cs.isError)
  143. {
  144. errIndex = i;
  145. return false;
  146. }
  147. }
  148. return !cs.arrayStart && !cs.jsonStart;
  149. }
  150. return false;
  151. }
  152. /// <summary>
  153. /// 获取值的长度(当Json值嵌套以"{"或"["开头时)
  154. /// </summary>
  155. private static int GetValueLength(string json, bool breakOnErr, out int errIndex)
  156. {
  157. errIndex = 0;
  158. int len = 0;
  159. if (!string.IsNullOrEmpty(json))
  160. {
  161. CharState cs = new CharState();
  162. char c;
  163. for (int i = 0; i < json.Length; i++)
  164. {
  165. c = json[i];
  166. if (!SetCharState(c, ref cs))//设置关键符号状态。
  167. {
  168. if (!cs.jsonStart && !cs.arrayStart)//json结束,又不是数组,则退出。
  169. {
  170. break;
  171. }
  172. }
  173. else if (cs.childrenStart)//正常字符,值状态下。
  174. {
  175. int length = GetValueLength(json.Substring(i), breakOnErr, out errIndex);//递归子值,返回一个长度。。。
  176. cs.childrenStart = false;
  177. cs.valueStart = 0;
  178. //cs.state = 0;
  179. i = i + length - 1;
  180. }
  181. if (breakOnErr && cs.isError)
  182. {
  183. errIndex = i;
  184. return i;
  185. }
  186. if (!cs.jsonStart && !cs.arrayStart)//记录当前结束位置。
  187. {
  188. len = i + 1;//长度比索引+1
  189. break;
  190. }
  191. }
  192. }
  193. return len;
  194. }
  195. /// <summary>
  196. /// 设置字符状态(返回true则为关键词,返回false则当为普通字符处理)
  197. /// </summary>
  198. private static bool SetCharState(char c, ref CharState cs)
  199. {
  200. cs.CheckIsError(c);
  201. switch (c)
  202. {
  203. case '{'://[{ "[{A}]":[{"[{B}]":3,"m":"C"}]}]
  204. #region 大括号
  205. if (cs.keyStart <= 0 && cs.valueStart <= 0)
  206. {
  207. cs.keyStart = 0;
  208. cs.valueStart = 0;
  209. if (cs.jsonStart && cs.state == 1)
  210. {
  211. cs.childrenStart = true;
  212. }
  213. else
  214. {
  215. cs.state = 0;
  216. }
  217. cs.jsonStart = true;//开始。
  218. return true;
  219. }
  220. #endregion
  221. break;
  222. case '}':
  223. #region 大括号结束
  224. if (cs.keyStart <= 0 && cs.valueStart < 2 && cs.jsonStart)
  225. {
  226. cs.jsonStart = false;//正常结束。
  227. cs.state = 0;
  228. cs.keyStart = 0;
  229. cs.valueStart = 0;
  230. cs.setDicValue = true;
  231. return true;
  232. }
  233. // cs.isError = !cs.jsonStart && cs.state == 0;
  234. #endregion
  235. break;
  236. case '[':
  237. #region 中括号开始
  238. if (!cs.jsonStart)
  239. {
  240. cs.arrayStart = true;
  241. return true;
  242. }
  243. else if (cs.jsonStart && cs.state == 1)
  244. {
  245. cs.childrenStart = true;
  246. return true;
  247. }
  248. #endregion
  249. break;
  250. case ']':
  251. #region 中括号结束
  252. if (cs.arrayStart && !cs.jsonStart && cs.keyStart <= 2 && cs.valueStart <= 0)//[{},333]//这样结束。
  253. {
  254. cs.keyStart = 0;
  255. cs.valueStart = 0;
  256. cs.arrayStart = false;
  257. return true;
  258. }
  259. #endregion
  260. break;
  261. case '"':
  262. case '\'':
  263. #region 引号
  264. if (cs.jsonStart || cs.arrayStart)
  265. {
  266. if (cs.state == 0)//key阶段,有可能是数组["aa",{}]
  267. {
  268. if (cs.keyStart <= 0)
  269. {
  270. cs.keyStart = (c == '"' ? 3 : 2);
  271. return true;
  272. }
  273. else if ((cs.keyStart == 2 && c == '\'') || (cs.keyStart == 3 && c == '"'))
  274. {
  275. if (!cs.escapeChar)
  276. {
  277. cs.keyStart = -1;
  278. return true;
  279. }
  280. else
  281. {
  282. cs.escapeChar = false;
  283. }
  284. }
  285. }
  286. else if (cs.state == 1 && cs.jsonStart)//值阶段必须是Json开始了。
  287. {
  288. if (cs.valueStart <= 0)
  289. {
  290. cs.valueStart = (c == '"' ? 3 : 2);
  291. return true;
  292. }
  293. else if ((cs.valueStart == 2 && c == '\'') || (cs.valueStart == 3 && c == '"'))
  294. {
  295. if (!cs.escapeChar)
  296. {
  297. cs.valueStart = -1;
  298. return true;
  299. }
  300. else
  301. {
  302. cs.escapeChar = false;
  303. }
  304. }
  305. }
  306. }
  307. #endregion
  308. break;
  309. case ':':
  310. #region 冒号
  311. if (cs.jsonStart && cs.keyStart < 2 && cs.valueStart < 2 && cs.state == 0)
  312. {
  313. if (cs.keyStart == 1)
  314. {
  315. cs.keyStart = -1;
  316. }
  317. cs.state = 1;
  318. return true;
  319. }
  320. // cs.isError = !cs.jsonStart || (cs.keyStart < 2 && cs.valueStart < 2 && cs.state == 1);
  321. #endregion
  322. break;
  323. case ',':
  324. #region 逗号 //["aa",{aa:12,}]
  325. if (cs.jsonStart)
  326. {
  327. if (cs.keyStart < 2 && cs.valueStart < 2 && cs.state == 1)
  328. {
  329. cs.state = 0;
  330. cs.keyStart = 0;
  331. cs.valueStart = 0;
  332. //if (cs.valueStart == 1)
  333. //{
  334. // cs.valueStart = 0;
  335. //}
  336. cs.setDicValue = true;
  337. return true;
  338. }
  339. }
  340. else if (cs.arrayStart && cs.keyStart <= 2)
  341. {
  342. cs.keyStart = 0;
  343. //if (cs.keyStart == 1)
  344. //{
  345. // cs.keyStart = -1;
  346. //}
  347. return true;
  348. }
  349. #endregion
  350. break;
  351. case ' ':
  352. case '\r':
  353. case '\n'://[ "a",\r\n{} ]
  354. case '\0':
  355. case '\t':
  356. if (cs.keyStart <= 0 && cs.valueStart <= 0) //cs.jsonStart &&
  357. {
  358. return true;//跳过空格。
  359. }
  360. break;
  361. default: //值开头。。
  362. if (c == '\\') //转义符号
  363. {
  364. if (cs.escapeChar)
  365. {
  366. cs.escapeChar = false;
  367. }
  368. else
  369. {
  370. cs.escapeChar = true;
  371. return true;
  372. }
  373. }
  374. else
  375. {
  376. cs.escapeChar = false;
  377. }
  378. if (cs.jsonStart || cs.arrayStart) // Json 或数组开始了。
  379. {
  380. if (cs.keyStart <= 0 && cs.state == 0)
  381. {
  382. cs.keyStart = 1;//无引号的
  383. }
  384. else if (cs.valueStart <= 0 && cs.state == 1 && cs.jsonStart)//只有Json开始才有值。
  385. {
  386. cs.valueStart = 1;//无引号的
  387. }
  388. }
  389. break;
  390. }
  391. return false;
  392. }
  393. }
  394. /// <summary>
  395. /// 字符状态
  396. /// </summary>
  397. public class CharState
  398. {
  399. internal bool jsonStart = false;//以 "{"开始了...
  400. internal bool setDicValue = false;// 可以设置字典值了。
  401. internal bool escapeChar = false;//以"\"转义符号开始了
  402. /// <summary>
  403. /// 数组开始【仅第一开头才算】,值嵌套的以【childrenStart】来标识。
  404. /// </summary>
  405. internal bool arrayStart = false;//以"[" 符号开始了
  406. internal bool childrenStart = false;//子级嵌套开始了。
  407. /// <summary>
  408. /// 【0 初始状态,或 遇到“,”逗号】;【1 遇到“:”冒号】
  409. /// </summary>
  410. internal int state = 0;
  411. /// <summary>
  412. /// 【-1 取值结束】【0 未开始】【1 无引号开始】【2 单引号开始】【3 双引号开始】
  413. /// </summary>
  414. internal int keyStart = 0;
  415. /// <summary>
  416. /// 【-1 取值结束】【0 未开始】【1 无引号开始】【2 单引号开始】【3 双引号开始】
  417. /// </summary>
  418. internal int valueStart = 0;
  419. internal bool isError = false;//是否语法错误。
  420. internal void CheckIsError(char c)//只当成一级处理(因为GetLength会递归到每一个子项处理)
  421. {
  422. if (keyStart > 1 || valueStart > 1)
  423. {
  424. return;
  425. }
  426. //示例 ["aa",{"bbbb":123,"fff","ddd"}]
  427. switch (c)
  428. {
  429. case '{'://[{ "[{A}]":[{"[{B}]":3,"m":"C"}]}]
  430. isError = jsonStart && state == 0;//重复开始错误 同时不是值处理。
  431. break;
  432. case '}':
  433. isError = !jsonStart || (keyStart != 0 && state == 0);//重复结束错误 或者 提前结束{"aa"}。正常的有{}
  434. break;
  435. case '[':
  436. isError = arrayStart && state == 0;//重复开始错误
  437. break;
  438. case ']':
  439. isError = !arrayStart || jsonStart;//重复开始错误 或者 Json 未结束
  440. break;
  441. case '"':
  442. case '\'':
  443. isError = !(jsonStart || arrayStart); //json 或数组开始。
  444. if (!isError)
  445. {
  446. //重复开始 [""",{"" "}]
  447. isError = (state == 0 && keyStart == -1) || (state == 1 && valueStart == -1);
  448. }
  449. if (!isError && arrayStart && !jsonStart && c == '\'')//['aa',{}]
  450. {
  451. isError = true;
  452. }
  453. break;
  454. case ':':
  455. isError = !jsonStart || state == 1;//重复出现。
  456. break;
  457. case ',':
  458. isError = !(jsonStart || arrayStart); //json 或数组开始。
  459. if (!isError)
  460. {
  461. if (jsonStart)
  462. {
  463. isError = state == 0 || (state == 1 && valueStart > 1);//重复出现。
  464. }
  465. else if (arrayStart)//["aa,] [,] [{},{}]
  466. {
  467. isError = keyStart == 0 && !setDicValue;
  468. }
  469. }
  470. break;
  471. case ' ':
  472. case '\r':
  473. case '\n'://[ "a",\r\n{} ]
  474. case '\0':
  475. case '\t':
  476. break;
  477. default: //值开头。。
  478. isError = (!jsonStart && !arrayStart) || (state == 0 && keyStart == -1) || (valueStart == -1 && state == 1);//
  479. break;
  480. }
  481. //if (isError)
  482. //{
  483. //}
  484. }
  485. }
  486. }