You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2244 lines
88 KiB

3 years ago
3 years ago
4 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. using Apewer;
  2. using Apewer.Internals;
  3. using Newtonsoft.Json;
  4. using Newtonsoft.Json.Linq;
  5. using System;
  6. using System.Collections;
  7. using System.Collections.Generic;
  8. using System.Collections.Specialized;
  9. #if !NET20
  10. using System.Dynamic;
  11. using System.IO;
  12. #endif
  13. using System.Reflection;
  14. using System.Runtime.Serialization;
  15. using System.Text;
  16. using static Apewer.NumberUtility;
  17. using static Apewer.RuntimeUtility;
  18. namespace Apewer
  19. {
  20. /// <summary>Json。</summary>
  21. [Serializable]
  22. public sealed class Json
  23. #if !NET20
  24. : DynamicObject
  25. #endif
  26. {
  27. #region 配置。
  28. [NonSerialized]
  29. private static bool _throw = false;
  30. [NonSerialized]
  31. private static bool _recursively = true;
  32. [NonSerialized]
  33. private static bool _forceall = true;
  34. /// <summary>允许产生 Exception,默认为不允许。</summary>
  35. public static bool AllowException { get { return _throw; } set { _throw = value; } }
  36. /// <summary>当存在递归引用时候包含递归项。指定为 True 时递归项为 Null 值,指定为 False 时不包含递归项。默认值:False。</summary>
  37. public static bool AllowRecursively { get { return _recursively; } set { _recursively = value; } }
  38. /// <summary>将所有类型视为拥有 <see cref="SerializableAttribute" /> 特性。</summary>
  39. /// <remarks>默认值:FALSE。</remarks>
  40. public static bool ForceAll { get => _forceall; set => _forceall = value; }
  41. #endregion
  42. #region 构造。
  43. #region 基础。
  44. [NonSerialized]
  45. private JToken _jtoken = null;
  46. [NonSerialized]
  47. private JArray _jarray = null;
  48. [NonSerialized]
  49. private JObject _jobject = null;
  50. [NonSerialized]
  51. private JProperty _jproperty = null;
  52. [NonSerialized]
  53. private JValue _jvalue = null;
  54. #endregion
  55. #region Reset
  56. /// <summary>重置当前对象为空。</summary>
  57. public void Reset()
  58. {
  59. Construct();
  60. }
  61. /// <summary>使用指定的文本重置当前对象。</summary>
  62. public bool Reset(string json)
  63. {
  64. Construct();
  65. if (json == null)
  66. {
  67. if (AllowException) throw new ArgumentNullException("json", "参数无效。");
  68. return false;
  69. }
  70. var parsed = From(json);
  71. if (parsed == null) return false;
  72. Construct(parsed._jtoken);
  73. return true;
  74. }
  75. /// <summary>使用指定的对象重置当前对象。</summary>
  76. /// <exception cref="System.Exception"></exception>
  77. /// <exception cref="System.ArgumentNullException"></exception>
  78. public bool Reset(Json json)
  79. {
  80. Construct();
  81. if (json == null)
  82. {
  83. if (AllowException) throw new ArgumentNullException("json", "参数无效。");
  84. return false;
  85. }
  86. var parsed = From(json.ToString());
  87. if (parsed == null) return false;
  88. Construct(parsed._jtoken);
  89. return true;
  90. }
  91. /// <summary>使用指定的字典对象重置当前对象。</summary>
  92. /// <exception cref="System.Exception"></exception>
  93. /// <exception cref="System.ArgumentNullException"></exception>
  94. public bool Reset(Dictionary<string, string> dictionary)
  95. {
  96. Construct();
  97. if (dictionary == null)
  98. {
  99. if (AllowException) throw new ArgumentNullException("dictionary", "参数无效。");
  100. return false;
  101. }
  102. var json = NewObject();
  103. foreach (var item in dictionary) json[item.Key] = item.Value;
  104. Construct(json._jtoken);
  105. return true;
  106. }
  107. /// <summary>使用指定的文本字典对象重置当前对象。</summary>
  108. /// <exception cref="System.Exception"></exception>
  109. /// <exception cref="System.ArgumentNullException"></exception>
  110. public bool Reset(TextSet dictionary)
  111. {
  112. Construct();
  113. if (dictionary == null)
  114. {
  115. if (AllowException) throw new ArgumentNullException("dictionary", "参数无效。");
  116. return false;
  117. }
  118. return Reset(dictionary.Origin);
  119. }
  120. /// <summary>使用指定的文本字典对象重置当前对象。</summary>
  121. /// <exception cref="System.Exception"></exception>
  122. /// <exception cref="System.ArgumentNullException"></exception>
  123. public bool Reset(ObjectSet<string> dictionary)
  124. {
  125. Construct();
  126. if (dictionary == null)
  127. {
  128. if (AllowException) throw new ArgumentNullException("dictionary", "参数无效。");
  129. return false;
  130. }
  131. return Reset(dictionary.Origin);
  132. }
  133. #endregion
  134. private void Construct(JToken jtoken = null)
  135. {
  136. _jtoken = jtoken;
  137. _jarray = null;
  138. _jobject = null;
  139. _jproperty = null;
  140. _jvalue = null;
  141. if (_jtoken != null)
  142. {
  143. if (_jtoken is JArray) _jarray = (JArray)_jtoken;
  144. if (_jtoken is JObject) _jobject = (JObject)_jtoken;
  145. if (_jtoken is JProperty) _jproperty = (JProperty)_jtoken;
  146. if (_jtoken is JValue) _jvalue = (JValue)_jtoken;
  147. }
  148. }
  149. private Json(JToken jtoken)
  150. {
  151. Construct(jtoken);
  152. }
  153. /// <summary>创建 Json Object 实例。</summary>
  154. public Json()
  155. {
  156. Construct(new JObject());
  157. }
  158. #endregion
  159. #region 属性。
  160. /// <summary>用于兼容 SimpleJson 的操作。</summary>
  161. public string this[string name]
  162. {
  163. get
  164. {
  165. var property = GetProperty(name);
  166. if (property == null) return "";
  167. return property.ToString();
  168. }
  169. set
  170. {
  171. SetProperty(name, value ?? "");
  172. }
  173. }
  174. private JTokenType TokenType
  175. {
  176. get
  177. {
  178. if (_jtoken == null) return JTokenType.None;
  179. else return _jtoken.Type;
  180. //if (_jtoken == null) return 0;
  181. //switch (_jtoken.Type)
  182. //{
  183. // case JTokenType.None: return 0;
  184. // case JTokenType.Object: return 1;
  185. // case JTokenType.Array: return 2;
  186. // case JTokenType.Constructor: return 3;
  187. // case JTokenType.Property: return 4;
  188. // case JTokenType.Comment: return 5;
  189. // case JTokenType.Integer: return 6;
  190. // case JTokenType.Float: return 7;
  191. // case JTokenType.String: return 8;
  192. // case JTokenType.Boolean: return 9;
  193. // case JTokenType.Null: return 10;
  194. // case JTokenType.Undefined: return 11;
  195. // case JTokenType.Date: return 12;
  196. // case JTokenType.Raw: return 13;
  197. // case JTokenType.Bytes: return 14;
  198. // case JTokenType.Guid: return 15;
  199. // case JTokenType.Uri: return 16;
  200. // case JTokenType.TimeSpan: return 17;
  201. // default: return 0;
  202. //}
  203. }
  204. }
  205. /// <summary>
  206. /// <para>获取当前实例的类型。可能的类型:</para>
  207. /// <para>None Object Array Constructor Property Comment Integer Float String</para>
  208. /// <para>Boolean Null Undefined Date Raw Bytes Guid Uri TimeSpan</para>
  209. /// </summary>
  210. public string Type { get { return TokenType.ToString(); } }
  211. /// <summary>实例有效。</summary>
  212. public
  213. bool Available
  214. { get { return _jtoken != null && TokenType != JTokenType.None; } }
  215. /// <summary>获取当前实例的值,当为 Json 格式时缩进。</summary>
  216. public string Lucid { get { return ToString(true); } }
  217. /// <summary>获取当前实例的值,当为 Json 格式时不缩进。</summary>
  218. public string Text { get { return ToString(false); } }
  219. /// <summary>当前实例类型为 Property 时,获取名称。</summary>
  220. public string Name
  221. {
  222. get { return _jproperty == null ? null : _jproperty.Name; }
  223. }
  224. /// <summary>获取值。</summary>
  225. public object Value
  226. {
  227. get
  228. {
  229. if (_jvalue != null)
  230. {
  231. if (_jvalue.Value == null) return null;
  232. if (_jvalue.Value is JValue jvalue) return jvalue.Value;
  233. if (_jvalue.Value is JToken jtoken) return new Json(jtoken);
  234. else return _jvalue.Value;
  235. }
  236. if (_jproperty != null)
  237. {
  238. if (_jproperty.Value == null) return null;
  239. if (_jproperty.Value is JValue jvalue) return jvalue.Value;
  240. if (_jproperty.Value is JToken jtoken) return new Json(jtoken);
  241. else return _jproperty.Value;
  242. }
  243. return null;
  244. }
  245. }
  246. /// <summary>实例无效。</summary>
  247. public bool IsNull { get { return _jtoken == null; } }
  248. #endregion
  249. #region Private Get
  250. private Json[] PrivateGetProperties { get { return GetProperties(); } }
  251. private Json[] PrivateGetValues { get { return GetValues(); } }
  252. private Json[] PrivateGetObjects { get { return GetObjects(); } }
  253. private Json[] PrivateGetItems { get { return GetItems(); } }
  254. #endregion
  255. #region Object : Get/Set
  256. /// <summary>获取所有类型为 Property 的子项。</summary>
  257. public Json[] GetProperties()
  258. {
  259. var ab = new ArrayBuilder<Json>();
  260. if (_jobject != null)
  261. {
  262. var children = _jobject.Children();
  263. foreach (var child in children)
  264. {
  265. var json = new Json(child);
  266. ab.Add(json);
  267. }
  268. }
  269. return ab.Export();
  270. }
  271. /// <summary>当前实例类型为 Object 时搜索属性,失败时返回 Null。</summary>
  272. /// <param name="name">将要搜索的属性名称,不可为 Null。</param>
  273. /// <exception cref="System.ArgumentNullException"></exception>
  274. /// <exception cref="System.InvalidOperationException"></exception>
  275. public Json GetProperty(string name)
  276. {
  277. if (_jobject == null || TokenType != JTokenType.Object)
  278. {
  279. if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
  280. return null;
  281. }
  282. if (name == null)
  283. {
  284. if (_throw) throw new ArgumentNullException("name", "参数无效。");
  285. return null;
  286. }
  287. var children = _jtoken.Children<JProperty>();
  288. foreach (var child in children)
  289. {
  290. if (child.Name == name)
  291. {
  292. var json = new Json(child.Value);
  293. return json;
  294. }
  295. }
  296. return null;
  297. }
  298. /// <summary>当前实例类型为 Object 时添加属性,值为 Null,已存在的属性将被替换。</summary>
  299. /// <param name="name">将要添加的属性名称,不可为 Null。</param>
  300. /// <exception cref="System.ArgumentNullException"></exception>
  301. /// <exception cref="System.InvalidOperationException"></exception>
  302. public bool SetProperty(string name)
  303. {
  304. if (_jobject == null || TokenType != JTokenType.Object)
  305. {
  306. if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
  307. return false;
  308. }
  309. if (name == null)
  310. {
  311. if (_throw) throw new ArgumentNullException("name", "参数无效。");
  312. return false;
  313. }
  314. var children = _jobject.Children<JProperty>();
  315. foreach (var child in children)
  316. {
  317. if (child.Name == name)
  318. {
  319. _jobject.Remove(name);
  320. break;
  321. }
  322. }
  323. _jobject.Add(name, null);
  324. return true;
  325. }
  326. /// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
  327. /// <param name="property">将要添加的属性。</param>
  328. /// <exception cref="System.ArgumentException"></exception>
  329. /// <exception cref="System.ArgumentNullException"></exception>
  330. /// <exception cref="System.InvalidOperationException"></exception>
  331. public bool SetProperty(Json property)
  332. {
  333. if (_jobject == null || TokenType != JTokenType.Object)
  334. {
  335. if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
  336. return false;
  337. }
  338. if (property == null)
  339. {
  340. if (_throw) throw new ArgumentNullException("property", "参数无效。");
  341. return false;
  342. }
  343. if (property._jproperty == null || property.TokenType != JTokenType.Property)
  344. {
  345. if (_throw) throw new ArgumentException("property", "将要设置的属性无效。");
  346. return false;
  347. }
  348. var name = property._jproperty.Name;
  349. var children = _jobject.Children<JProperty>();
  350. foreach (var child in children)
  351. {
  352. if (child.Name == name)
  353. {
  354. _jobject.Remove(name);
  355. break;
  356. }
  357. }
  358. _jobject.Add(name, property._jtoken);
  359. return true;
  360. }
  361. /// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
  362. /// <param name="name">将要添加的属性名称,不可为 Null。</param>
  363. /// <param name="value">将要添加的属性值。</param>
  364. /// <exception cref="System.ArgumentNullException"></exception>
  365. /// <exception cref="System.InvalidOperationException"></exception>
  366. public bool SetProperty(string name, bool value)
  367. {
  368. if (_jobject == null || TokenType != JTokenType.Object)
  369. {
  370. if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
  371. return false;
  372. }
  373. if (name == null)
  374. {
  375. if (_throw) throw new ArgumentNullException("name", "参数无效。");
  376. return false;
  377. }
  378. var children = _jobject.Children<JProperty>();
  379. foreach (var child in children)
  380. {
  381. if (child.Name == name)
  382. {
  383. _jobject.Remove(name);
  384. break;
  385. }
  386. }
  387. _jobject.Add(name, value);
  388. return true;
  389. }
  390. /// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
  391. /// <param name="name">将要添加的属性名称,不可为 Null。</param>
  392. /// <param name="value">将要添加的属性值。</param>
  393. /// <exception cref="System.ArgumentNullException"></exception>
  394. /// <exception cref="System.InvalidOperationException"></exception>
  395. public bool SetProperty(string name, string value)
  396. {
  397. if (_jobject == null || TokenType != JTokenType.Object)
  398. {
  399. if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
  400. return false;
  401. }
  402. if (name == null)
  403. {
  404. if (_throw) throw new ArgumentNullException("name", "参数无效。");
  405. return false;
  406. }
  407. var children = _jobject.Children<JProperty>();
  408. foreach (var child in children)
  409. {
  410. if (child.Name == name)
  411. {
  412. _jobject.Remove(name);
  413. break;
  414. }
  415. }
  416. _jobject.Add(name, value);
  417. return true;
  418. }
  419. /// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
  420. /// <param name="name">将要添加的属性名称,不可为 Null。</param>
  421. /// <param name="value">将要添加的属性值。</param>
  422. /// <exception cref="System.ArgumentNullException"></exception>
  423. /// <exception cref="System.InvalidOperationException"></exception>
  424. public bool SetProperty(string name, int value)
  425. {
  426. if (_jobject == null || TokenType != JTokenType.Object)
  427. {
  428. if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
  429. return false;
  430. }
  431. if (name == null)
  432. {
  433. if (_throw) throw new ArgumentNullException("name", "参数无效。");
  434. return false;
  435. }
  436. var children = _jobject.Children<JProperty>();
  437. foreach (var child in children)
  438. {
  439. if (child.Name == name)
  440. {
  441. _jobject.Remove(name);
  442. break;
  443. }
  444. }
  445. _jobject.Add(name, value);
  446. return true;
  447. }
  448. /// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
  449. /// <param name="name">将要添加的属性名称,不可为 Null。</param>
  450. /// <param name="value">将要添加的属性值。</param>
  451. /// <exception cref="System.ArgumentNullException"></exception>
  452. /// <exception cref="System.InvalidOperationException"></exception>
  453. public bool SetProperty(string name, long value)
  454. {
  455. if (_jobject == null || TokenType != JTokenType.Object)
  456. {
  457. if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
  458. return false;
  459. }
  460. if (name == null)
  461. {
  462. if (_throw) throw new ArgumentNullException("name", "参数无效。");
  463. return false;
  464. }
  465. var children = _jobject.Children<JProperty>();
  466. foreach (var child in children)
  467. {
  468. if (child.Name == name)
  469. {
  470. _jobject.Remove(name);
  471. break;
  472. }
  473. }
  474. _jobject.Add(name, value);
  475. return true;
  476. }
  477. /// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
  478. /// <param name="name">将要添加的属性名称,不可为 Null。</param>
  479. /// <param name="value">将要添加的属性值。</param>
  480. /// <exception cref="System.ArgumentNullException"></exception>
  481. /// <exception cref="System.InvalidOperationException"></exception>
  482. public bool SetProperty(string name, float value)
  483. {
  484. if (_jobject == null || TokenType != JTokenType.Object)
  485. {
  486. if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
  487. return false;
  488. }
  489. if (name == null)
  490. {
  491. if (_throw) throw new ArgumentNullException("name", "参数无效。");
  492. return false;
  493. }
  494. var children = _jobject.Children<JProperty>();
  495. foreach (var child in children)
  496. {
  497. if (child.Name == name)
  498. {
  499. _jobject.Remove(name);
  500. break;
  501. }
  502. }
  503. _jobject.Add(name, value);
  504. return true;
  505. }
  506. /// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
  507. /// <param name="name">将要添加的属性名称,不可为 Null。</param>
  508. /// <param name="value">将要添加的属性值。</param>
  509. /// <exception cref="System.ArgumentNullException"></exception>
  510. /// <exception cref="System.InvalidOperationException"></exception>
  511. public bool SetProperty(string name, double value)
  512. {
  513. if (_jobject == null || TokenType != JTokenType.Object)
  514. {
  515. if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
  516. return false;
  517. }
  518. if (name == null)
  519. {
  520. if (_throw) throw new ArgumentNullException("name", "参数无效。");
  521. return false;
  522. }
  523. var children = _jobject.Children<JProperty>();
  524. foreach (var child in children)
  525. {
  526. if (child.Name == name)
  527. {
  528. _jobject.Remove(name);
  529. break;
  530. }
  531. }
  532. _jobject.Add(name, value);
  533. return true;
  534. }
  535. /// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
  536. /// <param name="name">将要添加的属性名称,不可为 Null。</param>
  537. /// <param name="value">将要添加的属性值。</param>
  538. /// <exception cref="System.ArgumentNullException"></exception>
  539. /// <exception cref="System.InvalidOperationException"></exception>
  540. public bool SetProperty(string name, decimal value)
  541. {
  542. if (_jobject == null || TokenType != JTokenType.Object)
  543. {
  544. if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
  545. return false;
  546. }
  547. if (name == null)
  548. {
  549. if (_throw) throw new ArgumentNullException("name", "参数无效。");
  550. return false;
  551. }
  552. var children = _jobject.Children<JProperty>();
  553. foreach (var child in children)
  554. {
  555. if (child.Name == name)
  556. {
  557. _jobject.Remove(name);
  558. break;
  559. }
  560. }
  561. _jobject.Add(name, value);
  562. return true;
  563. }
  564. /// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
  565. /// <param name="name">将要添加的属性名称,不可为 Null。</param>
  566. /// <param name="value">将要添加的属性值。</param>
  567. /// <exception cref="System.ArgumentException"></exception>
  568. /// <exception cref="System.ArgumentNullException"></exception>
  569. /// <exception cref="System.InvalidOperationException"></exception>
  570. public bool SetProperty(string name, Json value)
  571. {
  572. if (_jobject == null || TokenType != JTokenType.Object)
  573. {
  574. if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
  575. return false;
  576. }
  577. if (name == null)
  578. {
  579. if (_throw) throw new ArgumentNullException("name", "参数无效。");
  580. return false;
  581. }
  582. var children = _jobject.Children<JProperty>();
  583. foreach (var child in children)
  584. {
  585. if (child.Name == name)
  586. {
  587. _jobject.Remove(name);
  588. break;
  589. }
  590. }
  591. if (value == null)
  592. {
  593. _jobject.Add(name, null);
  594. }
  595. else
  596. {
  597. if (value._jtoken == null)
  598. {
  599. _jobject.Add(name, null);
  600. }
  601. else
  602. {
  603. _jobject.Add(name, value._jtoken);
  604. }
  605. }
  606. return true;
  607. }
  608. #endregion
  609. #region Array
  610. /// <summary>获取所有类型为 Value 的子项。</summary>
  611. public Json[] GetValues()
  612. {
  613. var ab = new ArrayBuilder<Json>();
  614. if (_jarray != null)
  615. {
  616. var children = _jarray.Children<JValue>();
  617. foreach (var child in children)
  618. {
  619. var json = new Json(child);
  620. ab.Add(json);
  621. }
  622. }
  623. return ab.Export();
  624. }
  625. /// <summary>获取所有类型为 Object 的子项。</summary>
  626. public Json[] GetObjects()
  627. {
  628. var ab = new ArrayBuilder<Json>();
  629. if (_jarray != null)
  630. {
  631. var children = _jarray.Children<JObject>();
  632. foreach (var child in children)
  633. {
  634. var json = new Json(child);
  635. ab.Add(json);
  636. }
  637. }
  638. return ab.Export();
  639. }
  640. /// <summary>获取 Array 中的所有元素。</summary>
  641. public Json[] GetItems()
  642. {
  643. var ab = new ArrayBuilder<Json>();
  644. if (_jarray != null)
  645. {
  646. var children = _jarray.Children();
  647. foreach (var child in children)
  648. {
  649. var json = new Json(child);
  650. ab.Add(json);
  651. }
  652. }
  653. return ab.Export();
  654. }
  655. /// <summary>当前实例类型为 Array 时添加 Null 元素。</summary>
  656. /// <exception cref="System.InvalidOperationException"></exception>
  657. public bool AddItem()
  658. {
  659. if (_jarray == null || TokenType != JTokenType.Array)
  660. {
  661. if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
  662. return false;
  663. }
  664. _jarray.Add(JValue.CreateNull());
  665. return true;
  666. }
  667. /// <summary>当前实例类型为 Array 时添加元素。</summary>
  668. /// <param name="json">将要添加的元素。</param>
  669. /// <exception cref="System.InvalidOperationException"></exception>
  670. public bool AddItem(Json json)
  671. {
  672. if (json == null)
  673. {
  674. return AddItem();
  675. }
  676. if (_jarray == null || TokenType != JTokenType.Array)
  677. {
  678. if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
  679. return false;
  680. }
  681. if (json._jtoken == null || json.TokenType == JTokenType.None)
  682. {
  683. if (_throw) throw new ArgumentException("json", "将要设置的元素无效。");
  684. return false;
  685. }
  686. _jarray.Add(json._jtoken);
  687. return true;
  688. }
  689. /// <summary>当前实例类型为 Array 时添加元素。</summary>
  690. /// <param name="value">将要添加的元素。</param>
  691. /// <exception cref="System.InvalidOperationException"></exception>
  692. public bool AddItem(string value)
  693. {
  694. if (_jarray == null || TokenType != JTokenType.Array)
  695. {
  696. if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
  697. return false;
  698. }
  699. _jarray.Add(value ?? "");
  700. return true;
  701. }
  702. /// <summary>当前实例类型为 Array 时添加元素。</summary>
  703. /// <param name="value">将要添加的元素。</param>
  704. /// <exception cref="System.InvalidOperationException"></exception>
  705. public bool AddItem(bool value)
  706. {
  707. if (_jarray == null || TokenType != JTokenType.Array)
  708. {
  709. if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
  710. return false;
  711. }
  712. _jarray.Add(value);
  713. return true;
  714. }
  715. /// <summary>当前实例类型为 Array 时添加元素。</summary>
  716. /// <param name="value">将要添加的元素。</param>
  717. /// <exception cref="System.InvalidOperationException"></exception>
  718. public bool AddItem(int value)
  719. {
  720. if (_jarray == null || TokenType != JTokenType.Array)
  721. {
  722. if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
  723. return false;
  724. }
  725. _jarray.Add(value);
  726. return true;
  727. }
  728. /// <summary>当前实例类型为 Array 时添加元素。</summary>
  729. /// <param name="value">将要添加的元素。</param>
  730. /// <exception cref="System.InvalidOperationException"></exception>
  731. public bool AddItem(long value)
  732. {
  733. if (_jarray == null || TokenType != JTokenType.Array)
  734. {
  735. if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
  736. return false;
  737. }
  738. _jarray.Add(value);
  739. return true;
  740. }
  741. /// <summary>当前实例类型为 Array 时添加元素。</summary>
  742. /// <param name="value">将要添加的元素。</param>
  743. /// <exception cref="System.InvalidOperationException"></exception>
  744. public bool AddItem(float value)
  745. {
  746. if (_jarray == null || TokenType != JTokenType.Array)
  747. {
  748. if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
  749. return false;
  750. }
  751. _jarray.Add(value);
  752. return true;
  753. }
  754. /// <summary>当前实例类型为 Array 时添加元素。</summary>
  755. /// <param name="value">将要添加的元素。</param>
  756. /// <exception cref="System.InvalidOperationException"></exception>
  757. public bool AddItem(double value)
  758. {
  759. if (_jarray == null || TokenType != JTokenType.Array)
  760. {
  761. if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
  762. return false;
  763. }
  764. _jarray.Add(value);
  765. return true;
  766. }
  767. /// <summary>当前实例类型为 Array 时添加元素。</summary>
  768. /// <param name="value">将要添加的元素。</param>
  769. /// <exception cref="System.InvalidOperationException"></exception>
  770. public bool AddItem(decimal value)
  771. {
  772. if (_jarray == null || TokenType != JTokenType.Array)
  773. {
  774. if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
  775. return false;
  776. }
  777. _jarray.Add(value);
  778. return true;
  779. }
  780. /// <summary>从 Parent 中移除。</summary>
  781. /// <exception cref="System.InvalidOperationException"></exception>
  782. /// <exception cref="ArgumentOutOfRangeException"></exception>
  783. public bool Remove()
  784. {
  785. if (_jtoken == null) return false;
  786. if (_jtoken.Parent == null)
  787. {
  788. if (_throw) throw new InvalidOperationException("Parent 对象丢失。");
  789. return false;
  790. }
  791. try
  792. {
  793. _jtoken.Remove();
  794. return true;
  795. }
  796. catch (Exception exception)
  797. {
  798. if (_throw) throw exception;
  799. return false;
  800. }
  801. }
  802. #endregion
  803. #region Property
  804. /// <summary>Json 对象实例为空。</summary>
  805. public bool IsNone { get { return TokenType == JTokenType.None; } }
  806. /// <summary>Json 对象为 Object 实例。</summary>
  807. public bool IsObject { get { return TokenType == JTokenType.Object; } }
  808. /// <summary>Json 对象为 Array 实例。</summary>
  809. public bool IsArray { get { return TokenType == JTokenType.Array; } }
  810. /// <summary>Json 对象为 Property 实例。</summary>
  811. public bool IsProperty { get { return TokenType == JTokenType.Property; } }
  812. /// <summary>Json 对象为 String 实例。</summary>
  813. public bool IsString { get { return TokenType == JTokenType.String; } }
  814. /// <summary>当前实例类型为 Property 时设置 Null 值。</summary>
  815. /// <exception cref="System.InvalidOperationException"></exception>
  816. public bool SetValue()
  817. {
  818. var available = _jproperty != null && TokenType == JTokenType.Property;
  819. if (!available)
  820. {
  821. if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
  822. return false;
  823. }
  824. _jproperty.Value = JValue.CreateNull();
  825. return true;
  826. }
  827. /// <summary>当前实例类型为 Property 时设置值。</summary>
  828. /// <param name="value">将要设置的值。</param>
  829. /// <exception cref="System.InvalidOperationException"></exception>
  830. public bool SetValue(Json value)
  831. {
  832. var available = _jproperty != null && TokenType == JTokenType.Property;
  833. if (!available)
  834. {
  835. if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
  836. return false;
  837. }
  838. if (value == null)
  839. {
  840. _jproperty.Value = JValue.CreateNull();
  841. return true;
  842. }
  843. if (value._jtoken == null || value.TokenType == JTokenType.None)
  844. {
  845. _jproperty.Value = JValue.CreateNull();
  846. return true;
  847. }
  848. _jproperty.Value = new JValue(value._jtoken);
  849. return true;
  850. }
  851. /// <summary>当前实例类型为 Property 时设置值。</summary>
  852. /// <param name="value">将要设置的值。</param>
  853. /// <exception cref="System.InvalidOperationException"></exception>
  854. public bool SetValue(string value)
  855. {
  856. var available = _jproperty != null && TokenType == JTokenType.Property;
  857. if (!available)
  858. {
  859. if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
  860. return false;
  861. }
  862. _jproperty.Value = value == null ? JValue.CreateNull() : JValue.CreateString(value);
  863. return true;
  864. }
  865. /// <summary>当前实例类型为 Property 时设置值。</summary>
  866. /// <param name="value">将要设置的值。</param>
  867. /// <exception cref="System.InvalidOperationException"></exception>
  868. public bool SetValue(bool value)
  869. {
  870. var available = _jproperty != null && TokenType == JTokenType.Property;
  871. if (!available)
  872. {
  873. if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
  874. return false;
  875. }
  876. _jproperty.Value = new JValue(value);
  877. return true;
  878. }
  879. /// <summary>当前实例类型为 Property 时设置值。</summary>
  880. /// <param name="value">将要设置的值。</param>
  881. /// <exception cref="System.InvalidOperationException"></exception>
  882. public bool SetValue(int value)
  883. {
  884. var available = _jproperty != null && TokenType == JTokenType.Property;
  885. if (!available)
  886. {
  887. if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
  888. return false;
  889. }
  890. _jproperty.Value = new JValue(value);
  891. return true;
  892. }
  893. /// <summary>当前实例类型为 Property 时设置值。</summary>
  894. /// <param name="value">将要设置的值。</param>
  895. /// <exception cref="System.InvalidOperationException"></exception>
  896. public bool SetValue(long value)
  897. {
  898. var available = _jproperty != null && TokenType == JTokenType.Property;
  899. if (!available)
  900. {
  901. if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
  902. return false;
  903. }
  904. _jproperty.Value = new JValue(value);
  905. return true;
  906. }
  907. /// <summary>当前实例类型为 Property 时设置值。</summary>
  908. /// <param name="value">将要设置的值。</param>
  909. /// <exception cref="System.InvalidOperationException"></exception>
  910. public bool SetValue(float value)
  911. {
  912. var available = _jproperty != null && TokenType == JTokenType.Property;
  913. if (!available)
  914. {
  915. if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
  916. return false;
  917. }
  918. _jproperty.Value = new JValue(value);
  919. return true;
  920. }
  921. /// <summary>当前实例类型为 Property 时设置值。</summary>
  922. /// <param name="value">将要设置的值。</param>
  923. /// <exception cref="System.InvalidOperationException"></exception>
  924. public bool SetValue(double value)
  925. {
  926. var available = _jproperty != null && TokenType == JTokenType.Property;
  927. if (!available)
  928. {
  929. if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
  930. return false;
  931. }
  932. _jproperty.Value = new JValue(value);
  933. return true;
  934. }
  935. /// <summary>当前实例类型为 Property 时设置值。</summary>
  936. /// <param name="value">将要设置的值。</param>
  937. /// <exception cref="System.InvalidOperationException"></exception>
  938. public bool SetValue(decimal value)
  939. {
  940. var available = _jproperty != null && TokenType == JTokenType.Property;
  941. if (!available)
  942. {
  943. if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
  944. return false;
  945. }
  946. _jproperty.Value = new JValue(value);
  947. return true;
  948. }
  949. #endregion
  950. #region Import / Export
  951. #region String -> Json
  952. /// <summary>解析文本为 Json 对象,失败时返回 Null。</summary>
  953. /// <exception cref="System.Exception"></exception>
  954. public static Json From(string text)
  955. {
  956. try
  957. {
  958. var jtoken = JToken.Parse(text);
  959. var json = new Json(jtoken);
  960. return json;
  961. }
  962. catch (Exception exception)
  963. {
  964. if (AllowException) throw exception;
  965. return null;
  966. }
  967. }
  968. #endregion
  969. #region Object -> Json
  970. /// <summary>解析实现 IList 的对象为 Json 对象,失败时返回 Null。</summary>
  971. /// <param name="entity">将要解析的对象。</param>
  972. /// <param name="lower">在 Json 中将属性名称转换为小写。</param>
  973. /// <param name="depth">限制 Json 层级深度,当值小于零时将不限制深度。</param>
  974. /// <param name="force">强制解析属性,忽略 Serializable 特性。</param>
  975. public static Json From(IList entity, bool lower = false, int depth = -1, bool force = false)
  976. {
  977. if (entity == null) return null;
  978. var recursive = new object[] { entity };
  979. return From(entity, lower, recursive, depth, force);
  980. }
  981. /// <summary>解析实现 IDictionary 的对象为 Json 对象,失败时返回 Null。</summary>
  982. /// <param name="entity">将要解析的对象。</param>
  983. /// <param name="lower">在 Json 中将属性名称转换为小写。</param>
  984. /// <param name="depth">限制 Json 层级深度,当值小于零时将不限制深度。</param>
  985. /// <param name="force">强制解析属性,忽略 Serializable 特性。</param>
  986. public static Json From(IDictionary entity, bool lower = false, int depth = -1, bool force = false)
  987. {
  988. if (entity == null) return null;
  989. var recursive = new object[] { entity };
  990. return From(entity, lower, recursive, depth, force);
  991. }
  992. /// <summary>
  993. /// <para>解析对象为 Json 对象,包含所有公共属性,失败时返回 Null。</para>
  994. /// <para>String 对象将解析文本;Json 对象将返回实例;String 对象将解析文本;实现 IDictionary 或 IList 的对象将解析内容。</para>
  995. /// </summary>
  996. /// <param name="entity">将要解析的对象。</param>
  997. /// <param name="lower">在 Json 中将属性名称转换为小写。</param>
  998. /// <param name="depth">限制 Json 层级深度,当值小于零时将不限制深度。</param>
  999. /// <param name="force">强制解析属性,忽略 Serializable 特性。</param>
  1000. /// <exception cref="System.Exception"></exception>
  1001. public static Json From(object entity, bool lower = false, int depth = -1, bool force = false)
  1002. {
  1003. if (entity == null) return null;
  1004. var recursive = new object[] { entity };
  1005. return From(entity, lower, recursive, depth, force);
  1006. }
  1007. private static Json From(IList list, bool lower, object[] previous, int depth, bool force)
  1008. {
  1009. if (list == null) return null;
  1010. if (list is IToJson) return ((IToJson)list).ToJson();
  1011. var checker = list as IToJsonChecker;
  1012. var json = NewArray();
  1013. try
  1014. {
  1015. if (list is Array array)
  1016. {
  1017. if (array != null && array.Rank > 1)
  1018. {
  1019. ToJson(json, array, array.Rank, new int[0]);
  1020. return json;
  1021. }
  1022. }
  1023. foreach (var item in list)
  1024. {
  1025. // 由 IToJsonChecker 实现的方法检查是否包含元素。
  1026. if (checker != null && !checker.WithItemInJson(list, item)) continue;
  1027. var value = item;
  1028. // 检查递归引用。
  1029. var recursively = false;
  1030. foreach (var r in previous)
  1031. {
  1032. if (ReferenceEquals(r, value))
  1033. {
  1034. if (AllowRecursively) json.AddItem();
  1035. recursively = true;
  1036. break;
  1037. }
  1038. }
  1039. if (recursively) continue;
  1040. // 处理 Type 对象。
  1041. if (value.GetType().Equals(typeof(Type)) && (previous.Length > 2)) value = FullName((Type)value);
  1042. // 处理 Assembly 对象。
  1043. if (value.GetType().Equals(typeof(Assembly)) && (previous.Length > 2)) value = ((Assembly)value).FullName;
  1044. if (value == null) { json.AddItem(); }
  1045. else if (value is DateTime) { json.AddItem(value.ToString()); }
  1046. else if (value is bool) { json.AddItem((bool)value); }
  1047. else if (value is byte) { json.AddItem((byte)value); }
  1048. else if (value is sbyte) { json.AddItem((sbyte)value); }
  1049. else if (value is short) { json.AddItem((short)value); }
  1050. else if (value is ushort) { json.AddItem((ushort)value); }
  1051. else if (value is int) { json.AddItem((int)value); }
  1052. else if (value is uint) { json.AddItem((uint)value); }
  1053. else if (value is long) { json.AddItem((long)value); }
  1054. else if (value is ulong) { json.AddItem(value.ToString()); }
  1055. else if (value is float) { json.AddItem((float)value); }
  1056. else if (value is double) { json.AddItem((double)value); }
  1057. else if (value is decimal) { json.AddItem((decimal)value); }
  1058. else if (value is string) { json.AddItem((string)value); }
  1059. else if (value is Json) { json.AddItem(value as Json); }
  1060. else
  1061. {
  1062. if ((depth < 0) || (0 < depth && previous.Length < depth))
  1063. {
  1064. var recursive = new ArrayBuilder<object>(16);
  1065. recursive.Add(previous);
  1066. recursive.Add(value);
  1067. if (value is IDictionary<string, object> asExpando)
  1068. {
  1069. var expando = new Dictionary<string, object>(asExpando);
  1070. json.AddItem(From(expando, lower, recursive, depth, force));
  1071. }
  1072. else if (value is IDictionary) { json.AddItem(From(value as IDictionary, lower, recursive, depth, force)); }
  1073. else if (value is IList) { json.AddItem(From(value as IList, lower, recursive, depth, force)); }
  1074. else { json.AddItem(From(value, lower, recursive, depth, force)); }
  1075. }
  1076. else
  1077. {
  1078. json.AddItem(value.ToString());
  1079. }
  1080. }
  1081. }
  1082. }
  1083. catch { }
  1084. return json;
  1085. }
  1086. private static Json From(IDictionary dictionary, bool lower, object[] previous, int depth, bool force)
  1087. {
  1088. if (dictionary == null) return null;
  1089. if (dictionary is IToJson) return ((IToJson)dictionary).ToJson();
  1090. // IDictionary 不再需要 SerializableAttribute 特性。
  1091. // {
  1092. // var dtype = dictionary.GetType();
  1093. // var sas = dtype.GetCustomAttributes(typeof(SerializableAttribute), false);
  1094. // if (sas == null || sas.Length < 1) return null;
  1095. // }
  1096. var checker = dictionary as IToJsonChecker;
  1097. var json = NewObject();
  1098. try
  1099. {
  1100. var keys = dictionary.Keys;
  1101. foreach (var key in keys)
  1102. {
  1103. if (key == null) continue;
  1104. try
  1105. {
  1106. var field = key.ToString() ?? "";
  1107. if (lower && !string.IsNullOrEmpty(field)) field = field.ToLower();
  1108. var value = dictionary[key];
  1109. // 检查递归引用。
  1110. var recursively = false;
  1111. foreach (var r in previous)
  1112. {
  1113. if (ReferenceEquals(r, value))
  1114. {
  1115. if (AllowRecursively) json.SetProperty(field);
  1116. recursively = true;
  1117. break;
  1118. }
  1119. }
  1120. if (recursively) continue;
  1121. // 检查 System.Attribute.TypeId。
  1122. if (field == "TypeId" || field == "typeid")
  1123. {
  1124. if ((value != null) && (value is Type))
  1125. {
  1126. json.SetProperty(field, FullName((Type)value));
  1127. continue;
  1128. }
  1129. }
  1130. // 由 IToJsonChecker 实现的方法检查是否包含元素。
  1131. if (checker != null && !checker.WithPropertyInJson(dictionary, field, value)) continue;
  1132. if (value != null)
  1133. {
  1134. // 处理 Type 对象。
  1135. if (value.GetType().Equals(typeof(Type)) && (previous.Length > 2))
  1136. {
  1137. value = FullName((Type)value);
  1138. }
  1139. // 处理 Assembly 对象。
  1140. if (value.GetType().Equals(typeof(Assembly)) && (previous.Length > 2))
  1141. {
  1142. value = ((Assembly)value).FullName;
  1143. }
  1144. }
  1145. if (value == null) { json.SetProperty(field); }
  1146. else if (value is DateTime) { json.SetProperty(field, value.ToString()); }
  1147. else if (value is bool) { json.SetProperty(field, (bool)value); }
  1148. else if (value is byte) { json.SetProperty(field, (byte)value); }
  1149. else if (value is sbyte) { json.SetProperty(field, (sbyte)value); }
  1150. else if (value is short) { json.SetProperty(field, (short)value); }
  1151. else if (value is ushort) { json.SetProperty(field, (ushort)value); }
  1152. else if (value is int) { json.SetProperty(field, (int)value); }
  1153. else if (value is uint) { json.SetProperty(field, (uint)value); }
  1154. else if (value is long) { json.SetProperty(field, (long)value); }
  1155. else if (value is ulong) { json.SetProperty(field, value.ToString()); }
  1156. else if (value is float) { json.SetProperty(field, (float)value); }
  1157. else if (value is double) { json.SetProperty(field, (double)value); }
  1158. else if (value is decimal) { json.SetProperty(field, (decimal)value); }
  1159. else if (value is string) { json.SetProperty(field, (string)value); }
  1160. else if (value is Json) { json.SetProperty(field, value as Json); }
  1161. else
  1162. {
  1163. if ((depth < 0) || (0 < depth && previous.Length < depth))
  1164. {
  1165. var recursive = new ArrayBuilder<object>(16);
  1166. recursive.Add(previous);
  1167. recursive.Add(value);
  1168. if (value is IDictionary) { json.SetProperty(field, From(value as IDictionary, lower, recursive, depth, force)); }
  1169. else if (value is IList) { json.SetProperty(field, From(value as IList, lower, recursive, depth, force)); }
  1170. else { json.SetProperty(field, From(value, lower, recursive, depth, force)); }
  1171. }
  1172. else
  1173. {
  1174. json.SetProperty(field, value.ToString());
  1175. }
  1176. }
  1177. }
  1178. catch { }
  1179. }
  1180. }
  1181. catch { }
  1182. return json;
  1183. }
  1184. private static Json From(object entity, bool lower, object[] previous, int depth, bool force)
  1185. {
  1186. if (entity == null) return null;
  1187. if (entity is IToJson) return ((IToJson)entity).ToJson();
  1188. if (entity is string) return From(entity as string);
  1189. // 递归检查。
  1190. var pab = new ArrayBuilder<object>(16);
  1191. if (previous != null) pab.Add(previous as IEnumerable<object>);
  1192. pab.Add(entity);
  1193. var end = depth > 0 && pab.Count >= depth;
  1194. // 不可递归类型:类型。
  1195. if (entity is Type)
  1196. {
  1197. var t = entity as Type;
  1198. if (t.Equals(typeof(void))) return null;
  1199. var tJson = NewObject();
  1200. if (end) tJson.SetProperty(lower ? "name" : "Name", FullName(t));
  1201. else
  1202. {
  1203. tJson.SetProperty(lower ? "name" : "Name", t.Name);
  1204. if (t.IsGenericType)
  1205. {
  1206. tJson.SetProperty(lower ? "generic" : "Generic", From(t.GetGenericArguments(), lower, pab, 2, true));
  1207. }
  1208. tJson.SetProperty(lower ? "namespace" : "Namespace", t.Namespace);
  1209. }
  1210. tJson.SetProperty(lower ? "assembly" : "Assembly", t.Assembly.Location);
  1211. if (end)
  1212. {
  1213. tJson.SetProperty(lower ? "properties" : "Properties", t.GetProperties().Length);
  1214. tJson.SetProperty(lower ? "methods" : "Methods", t.GetMethods().Length);
  1215. }
  1216. else
  1217. {
  1218. tJson.SetProperty(lower ? "properties" : "Properties", From(t.GetProperties(), lower, new object[0], 1, true));
  1219. tJson.SetProperty(lower ? "methods" : "Methods", From(t.GetMethods(), lower, new object[0], 1, true));
  1220. }
  1221. return tJson;
  1222. }
  1223. // 不可递归类型:方法。
  1224. if (entity is MethodBase)
  1225. {
  1226. var mb = entity as MethodBase;
  1227. var mbJson = NewObject();
  1228. mbJson.SetProperty(lower ? "name" : "Name", mb.Name);
  1229. mbJson.SetProperty(lower ? "declaring" : "Declaring", FullName(mb.DeclaringType));
  1230. if (mb.IsStatic) mbJson.SetProperty(lower ? "static" : "Static", mb.IsStatic);
  1231. if (mb is MethodInfo mi)
  1232. {
  1233. mbJson.SetProperty(lower ? "type" : "Type", FullName(mi.ReturnType));
  1234. }
  1235. mbJson.SetProperty(lower ? "parameters" : "Parameters", mb.GetParameters().Length);
  1236. return mbJson;
  1237. }
  1238. // 不可递归类型:成员。
  1239. if (entity is MemberInfo)
  1240. {
  1241. var mi = entity as MemberInfo;
  1242. var miJson = NewObject();
  1243. miJson.SetProperty(lower ? "name" : "Name", mi.Name);
  1244. miJson.SetProperty(lower ? "declaring" : "Declaring", FullName(mi.DeclaringType));
  1245. miJson.SetProperty(lower ? "type" : "Type", mi.MemberType.ToString());
  1246. if (mi is PropertyInfo pi)
  1247. {
  1248. var getter = pi.GetGetMethod();
  1249. var setter = pi.GetSetMethod();
  1250. var isStatic = (getter != null && getter.IsStatic) || (setter != null && setter.IsStatic);
  1251. if (isStatic) miJson.SetProperty(lower ? "static" : "Static", isStatic);
  1252. miJson.SetProperty(lower ? "get" : "Get", getter != null);
  1253. miJson.SetProperty(lower ? "set" : "Set", setter != null);
  1254. }
  1255. else if (mi is FieldInfo fi)
  1256. {
  1257. if (fi.IsStatic) miJson.SetProperty(lower ? "static" : "Static", true);
  1258. }
  1259. return miJson;
  1260. }
  1261. // 不可递归类型:参数。
  1262. if (entity is ParameterInfo)
  1263. {
  1264. var pi = entity as ParameterInfo;
  1265. var piJson = NewObject();
  1266. piJson.SetProperty(lower ? "name" : "Name", pi.Name);
  1267. piJson.SetProperty(lower ? "type" : "Type", FullName(pi.ParameterType));
  1268. return piJson;
  1269. }
  1270. // 强制序列化。
  1271. var exception = entity as Exception;
  1272. if (exception != null) force = true;
  1273. if (!(force || _forceall) && !CanSerialize(entity.GetType(), false)) return null;
  1274. if (entity is Json) { if (lower) Lower(entity as Json); return entity as Json; }
  1275. else if (entity is String) { return From((string)entity); }
  1276. else if (entity is IDictionary<string, object> asExpando) { return From(new Dictionary<string, object>(asExpando), lower, depth, force); }
  1277. else if (entity is IDictionary) { return From(entity as IDictionary, lower, depth, force); }
  1278. else if (entity is IList) { return From(entity as IList, lower, depth, force); }
  1279. else if (entity is NameValueCollection nc) { return From(CollectionUtility.Dictionary(nc), lower, depth, force); }
  1280. var type = entity.GetType();
  1281. var independent = RuntimeUtility.Contains<IndependentAttribute>(type);
  1282. var checker = entity as IToJsonChecker;
  1283. var properties = type.GetProperties();
  1284. if (properties.LongLength > 0L)
  1285. {
  1286. var dict = new Dictionary<string, object>();
  1287. // 添加异常类型,并提前加入基类属性。
  1288. if (exception != null)
  1289. {
  1290. dict.Add(lower ? "type" : "Type", FullName(exception.GetType()));
  1291. dict.Add(lower ? "message" : "Message", Message(exception));
  1292. var exData = exception.Data;
  1293. if (exData != null && exData.Count > 0) dict.Add(lower ? "data" : "Data", exData);
  1294. var exHelpLink = exception.HelpLink;
  1295. if (!string.IsNullOrEmpty(exHelpLink)) dict.Add(lower ? "help" : "Help", exHelpLink);
  1296. if (!end)
  1297. {
  1298. var stackJson = NewArray();
  1299. var stackJsonLength = 0;
  1300. var stackText = exception.StackTrace;
  1301. if (!string.IsNullOrEmpty(stackText))
  1302. {
  1303. var stackSplit = exception.StackTrace.Split('\r', '\n');
  1304. foreach (var stackItem in stackSplit)
  1305. {
  1306. if (string.IsNullOrEmpty(stackItem)) continue;
  1307. var stackTrim = stackItem.Trim();
  1308. if (string.IsNullOrEmpty(stackTrim)) continue;
  1309. stackJson.AddItem(stackTrim);
  1310. stackJsonLength += 1;
  1311. }
  1312. }
  1313. if (stackJsonLength > 0) dict.Add(lower ? "stack" : "Stack", stackJson);
  1314. var exTargetSite = exception.TargetSite;
  1315. if (exTargetSite != null) dict.Add(lower ? "target" : "Target", From(exTargetSite, lower, pab, depth, true));
  1316. }
  1317. var innerEx = exception.InnerException;
  1318. if (innerEx != null)
  1319. {
  1320. if (end) dict.Add(lower ? "inner" : "InnerException", FullName(innerEx.GetType()));
  1321. else dict.Add(lower ? "inner" : "InnerException", From(innerEx, lower, pab, depth, true));
  1322. }
  1323. }
  1324. foreach (var property in properties)
  1325. {
  1326. var field = property.Name;
  1327. if (field == null) continue;
  1328. // 有 Independent 的对象不包含继承属性。
  1329. if (independent)
  1330. {
  1331. if (!property.DeclaringType.Equals(type)) continue;
  1332. }
  1333. // 异常不包含基类中的属性。
  1334. if (exception != null)
  1335. {
  1336. if (property.DeclaringType.Equals(typeof(Exception))) continue;
  1337. }
  1338. // 处理 Assembly 对象的 DefinedTypes 和 ExportedTypes 属性。
  1339. if (entity is Assembly)
  1340. {
  1341. var assembly = entity as Assembly;
  1342. if (assembly != null)
  1343. {
  1344. if (field == "DefinedTypes" || field == "ExportedTypes")
  1345. {
  1346. continue;
  1347. }
  1348. }
  1349. }
  1350. var getter = property.GetGetMethod(false);
  1351. if (getter == null) continue;
  1352. if (getter.IsStatic) continue;
  1353. var value = null as object;
  1354. try
  1355. {
  1356. value = getter.Invoke((object)entity, null);
  1357. // 由 IToJsonChecker 实现的方法检查是否包含元素。
  1358. if (checker != null && !checker.WithPropertyInJson(entity, property, value)) continue;
  1359. // 处理 Type 对象。
  1360. if (getter.ReturnType.Equals(typeof(Type)) && (previous.Length > 2))
  1361. {
  1362. value = FullName((Type)value);
  1363. }
  1364. // 处理 Assembly 对象。
  1365. if (getter.ReturnType.Equals(typeof(Assembly)) && (previous.Length > 2))
  1366. {
  1367. value = ((Assembly)value).FullName;
  1368. }
  1369. }
  1370. catch (Exception ex)
  1371. {
  1372. value = ex.Message;
  1373. }
  1374. if (!dict.ContainsKey(field)) dict.Add(field, value);
  1375. }
  1376. var json = From(dict, lower, previous, depth, force);
  1377. return json;
  1378. }
  1379. else
  1380. {
  1381. return NewObject();
  1382. }
  1383. }
  1384. private static void ToJson(Json parent, Array array, int rank, int[] indices)
  1385. {
  1386. var dimension = indices.Length;
  1387. var subIndices = new int[dimension + 1];
  1388. if (dimension > 0) indices.CopyTo(subIndices, 0);
  1389. var subLength = array.GetLength(dimension);
  1390. var end = dimension + 1 >= rank;
  1391. if (end)
  1392. {
  1393. var subLinear = new object[subLength];
  1394. for (var i = 0; i < subLength; i++)
  1395. {
  1396. subIndices[dimension] = i;
  1397. subLinear[i] = array.GetValue(subIndices);
  1398. }
  1399. var subJson = Json.From(subLinear);
  1400. parent.Reset(subJson);
  1401. }
  1402. else
  1403. {
  1404. for (var i = 0; i < subLength; i++)
  1405. {
  1406. subIndices[dimension] = i;
  1407. var subJson = Json.NewArray();
  1408. ToJson(subJson, array, rank, subIndices);
  1409. parent.AddItem(subJson);
  1410. }
  1411. }
  1412. }
  1413. #endregion
  1414. #region Json -> String
  1415. /// <summary>导出文本,可指定缩进。若类型为 String,则导出 String 值,忽略缩进。</summary>
  1416. internal static string Export(Json json, bool indented)
  1417. {
  1418. if (json == null) return "";
  1419. if (json._jtoken == null) return "";
  1420. if (json.TokenType == JTokenType.String && json._jvalue != null)
  1421. {
  1422. return json._jvalue.Value.ToString();
  1423. }
  1424. return json._jtoken.ToString(indented ? Formatting.Indented : Formatting.None);
  1425. }
  1426. /// <summary>生成字符串,默认不缩进。若类型为 String,则导出 String 值。</summary>
  1427. public override string ToString() => Export(this, false);
  1428. /// <summary>生成字符串,可指定缩进。若类型为 String,则导出 String 值,忽略缩进。</summary>
  1429. public string ToString(bool indented) => Export(this, indented);
  1430. #endregion
  1431. #region Json -> Object
  1432. /// <summary>填充类型实例,失败时返回 NULL 值。</summary>
  1433. internal static T Object<T>(Json json, bool ignoreCase = true, string ignoreCharacters = null, bool force = false) where T : class, new()
  1434. {
  1435. if (json == null) return null;
  1436. if (json._jtoken == null) return null;
  1437. if (json.TokenType != JTokenType.Object) return null;
  1438. var entity = Activator.CreateInstance(typeof(T));
  1439. Object(entity, json, ignoreCase, ignoreCharacters, force);
  1440. return (T)entity;
  1441. }
  1442. /// <summary>将 Json 填充到数组列表,失败时返回 NULL 值。</summary>
  1443. internal static T[] Array<T>(Json json, bool ignoreCase = true, string ignoreCharacters = null, bool force = false)
  1444. {
  1445. if (json == null) return null;
  1446. if (json._jtoken == null) return null;
  1447. if (json.TokenType != JTokenType.Array) return null;
  1448. var list = new List<T>();
  1449. Array(list, json, ignoreCase, ignoreCharacters, force);
  1450. return list.ToArray();
  1451. }
  1452. /// <summary></summary>
  1453. public static void Object(object entity, Json json, bool ignoreCase, string ignoreCharacters, bool force)
  1454. {
  1455. if (entity == null || json == null) return;
  1456. if (json.TokenType != JTokenType.Object) return;
  1457. var jps = json.GetProperties();
  1458. if (jps.Length < 1) return;
  1459. var etype = entity.GetType();
  1460. var eps = etype.GetProperties();
  1461. if (eps.Length < 1) return;
  1462. foreach (var ep in eps)
  1463. {
  1464. foreach (var jp in jps)
  1465. {
  1466. var jpn = TextUtility.Trim(jp.Name);
  1467. var epn = TextUtility.Trim(ep.Name);
  1468. if (ignoreCharacters != null)
  1469. {
  1470. var characters = ignoreCharacters.ToCharArray();
  1471. foreach (var character in characters)
  1472. {
  1473. jpn.Replace(character.ToString(), "");
  1474. epn.Replace(character.ToString(), "");
  1475. }
  1476. }
  1477. if (ignoreCase)
  1478. {
  1479. if (jpn.Length > 0) jpn = jpn.ToLower();
  1480. if (epn.Length > 0) epn = epn.ToLower();
  1481. }
  1482. if (jpn.Length < 1 || epn.Length < 1) continue;
  1483. if (jpn != epn) continue;
  1484. var value = jp.Value;
  1485. if (value == null) continue;
  1486. Property(entity, ep, value, ignoreCase, ignoreCharacters, force);
  1487. }
  1488. }
  1489. }
  1490. static void Add(object entity, object item, int index)
  1491. {
  1492. try
  1493. {
  1494. if (entity is Array array) array.SetValue(item, index);
  1495. else if (entity is IList list) list.Add(item);
  1496. }
  1497. catch (Exception ex)
  1498. {
  1499. if (_throw) throw ex;
  1500. }
  1501. }
  1502. internal static void Array(object array, Json json, bool ignoreCase, string ignoreCharacters, bool force)
  1503. {
  1504. if (array == null) return;
  1505. if (json == null) return;
  1506. if (json.TokenType != JTokenType.Array) return;
  1507. var type = array.GetType();
  1508. var subtype = null as Type;
  1509. if (array is Array)
  1510. {
  1511. string typeName = FullName(array.GetType()).Replace("[]", string.Empty);
  1512. subtype = array.GetType().Assembly.GetType(typeName);
  1513. }
  1514. else
  1515. {
  1516. var subtypes = type.GetGenericArguments();
  1517. if (subtypes.Length < 1) return;
  1518. subtype = subtypes[0];
  1519. }
  1520. var jis = json.GetItems();
  1521. for (var index = 0; index < jis.Length; index++)
  1522. {
  1523. var ji = jis[index];
  1524. if (subtype.Equals(typeof(Json))) Add(array, ji, index);
  1525. else if (subtype.Equals(typeof(string))) Add(array, (ji.TokenType == JTokenType.Null) ? null : ji.Text, index);
  1526. else if (subtype.Equals(typeof(byte))) Add(array, Byte(ji.Text), index);
  1527. else if (subtype.Equals(typeof(short))) Add(array, Int16(ji.Text), index);
  1528. else if (subtype.Equals(typeof(int))) Add(array, Int32(ji.Text), index);
  1529. else if (subtype.Equals(typeof(long))) Add(array, Int64(ji.Text), index);
  1530. else if (subtype.Equals(typeof(sbyte))) Add(array, SByte(ji.Text), index);
  1531. else if (subtype.Equals(typeof(ushort))) Add(array, UInt16(ji.Text), index);
  1532. else if (subtype.Equals(typeof(uint))) Add(array, UInt32(ji.Text), index);
  1533. else if (subtype.Equals(typeof(ulong))) Add(array, UInt64(ji.Text), index);
  1534. else if (subtype.Equals(typeof(float))) Add(array, Single(ji.Text), index);
  1535. else if (subtype.Equals(typeof(double))) Add(array, Double(ji.Text), index);
  1536. else if (subtype.Equals(typeof(decimal))) Add(array, Decimal(ji.Text), index);
  1537. else
  1538. {
  1539. var serializable = (force || _forceall) ? true : CanSerialize(subtype, false);
  1540. if (serializable && (ji is Json))
  1541. {
  1542. switch (ji.TokenType)
  1543. {
  1544. case JTokenType.Object:
  1545. var subobject = Activator.CreateInstance(subtype);
  1546. Object(subobject, ji, ignoreCase, ignoreCharacters, force);
  1547. Add(array, subobject, index);
  1548. break;
  1549. case JTokenType.Array:
  1550. var subarray = Activator.CreateInstance(subtype);
  1551. Array(subarray, ji, ignoreCase, ignoreCharacters, force);
  1552. Add(array, subarray, index);
  1553. break;
  1554. }
  1555. }
  1556. }
  1557. }
  1558. }
  1559. private static void Property(object entity, PropertyInfo property, object value, bool ignoreCase, string ignoreCharacters, bool force)
  1560. {
  1561. if (entity == null) return;
  1562. if (property == null) return;
  1563. if (value == null) return;
  1564. var setter = property.GetSetMethod();
  1565. if (setter == null) return;
  1566. var pt = property.PropertyType;
  1567. var ptname = FullName(property.PropertyType);
  1568. if (ptname == FullName(typeof(Json)))
  1569. {
  1570. if (value is Json) setter.Invoke(entity, new object[] { value });
  1571. }
  1572. else
  1573. {
  1574. if (pt.Equals(typeof(DateTime)))
  1575. {
  1576. try
  1577. {
  1578. setter.Invoke(entity, new object[] { DateTime.Parse(value.ToString()) });
  1579. }
  1580. catch (Exception exception)
  1581. {
  1582. if (AllowException) throw exception;
  1583. setter.Invoke(entity, new object[] { "" });
  1584. }
  1585. }
  1586. else if (pt.Equals(typeof(string)))
  1587. {
  1588. if (value is Json asJson) setter.Invoke(entity, new object[] { ((Json)value).TokenType == JTokenType.Null ? null : ((Json)value).Text });
  1589. else setter.Invoke(entity, new object[] { value.ToString() });
  1590. }
  1591. else if (pt.Equals(typeof(bool))) setter.Invoke(entity, new object[] { Boolean(value) });
  1592. else if (pt.Equals(typeof(byte))) setter.Invoke(entity, new object[] { Byte(value) });
  1593. else if (pt.Equals(typeof(sbyte))) setter.Invoke(entity, new object[] { SByte(value) });
  1594. else if (pt.Equals(typeof(short))) setter.Invoke(entity, new object[] { Int16(value) });
  1595. else if (pt.Equals(typeof(ushort))) setter.Invoke(entity, new object[] { UInt16(value) });
  1596. else if (pt.Equals(typeof(int))) setter.Invoke(entity, new object[] { Int32(value) });
  1597. else if (pt.Equals(typeof(uint))) setter.Invoke(entity, new object[] { UInt32(value) });
  1598. else if (pt.Equals(typeof(long))) setter.Invoke(entity, new object[] { Int64(value) });
  1599. else if (pt.Equals(typeof(ulong))) setter.Invoke(entity, new object[] { UInt64(value) });
  1600. else if (pt.Equals(typeof(float))) setter.Invoke(entity, new object[] { Float(value) });
  1601. else if (pt.Equals(typeof(double))) setter.Invoke(entity, new object[] { Double(value) });
  1602. else if (pt.Equals(typeof(decimal))) setter.Invoke(entity, new object[] { Decimal(value) });
  1603. else
  1604. {
  1605. var serializable = (force || _forceall);
  1606. if (!serializable) serializable = CanSerialize(property.PropertyType, false);
  1607. if (serializable && (value is Json))
  1608. {
  1609. switch (((Json)value).TokenType)
  1610. {
  1611. case JTokenType.Object:
  1612. var subobject = Activator.CreateInstance(property.PropertyType);
  1613. Object(subobject, (Json)value, ignoreCase, ignoreCharacters, force);
  1614. setter.Invoke(entity, new object[] { subobject });
  1615. break;
  1616. case JTokenType.Array:
  1617. object subarray;
  1618. if (pt.BaseType != null && pt.BaseType.Equals(typeof(Array)))
  1619. {
  1620. subarray = new object();
  1621. var length = ((Json)value).GetItems().Length;
  1622. subarray = pt.InvokeMember("Set", BindingFlags.CreateInstance, null, subarray, new object[] { length });
  1623. }
  1624. else
  1625. {
  1626. subarray = Activator.CreateInstance(property.PropertyType);
  1627. }
  1628. Array(subarray, (Json)value, ignoreCase, ignoreCharacters, force);
  1629. setter.Invoke(entity, new object[] { subarray });
  1630. break;
  1631. }
  1632. }
  1633. }
  1634. }
  1635. }
  1636. #endregion
  1637. #endregion
  1638. #region Dynamic
  1639. #if !NET20
  1640. /// <summary></summary>
  1641. public override bool TryGetMember(GetMemberBinder binder, out object result)
  1642. {
  1643. var contains = false;
  1644. if (IsObject)
  1645. {
  1646. var property = GetProperty(binder.Name);
  1647. contains = property != null;
  1648. result = contains ? property.Value : null;
  1649. return contains;
  1650. }
  1651. result = null;
  1652. return contains;
  1653. }
  1654. /// <summary></summary>
  1655. public override bool TrySetMember(SetMemberBinder binder, object value)
  1656. {
  1657. var name = binder.Name;
  1658. if (value == null) return SetProperty(name);
  1659. if (value is Json) return SetProperty(name, (Json)value);
  1660. if (value is string) return SetProperty(name, (string)value);
  1661. if (value is bool) return SetProperty(name, (bool)value);
  1662. if (value is byte) return SetProperty(name, (byte)value);
  1663. if (value is sbyte) return SetProperty(name, (sbyte)value);
  1664. if (value is short) return SetProperty(name, (short)value);
  1665. if (value is ushort) return SetProperty(name, (ushort)value);
  1666. if (value is int) return SetProperty(name, (int)value);
  1667. if (value is uint) return SetProperty(name, (uint)value);
  1668. if (value is long) return SetProperty(name, (long)value);
  1669. if (value is float) return SetProperty(name, (float)value);
  1670. if (value is double) return SetProperty(name, (double)value);
  1671. if (value is decimal) return SetProperty(name, (decimal)value);
  1672. return false;
  1673. }
  1674. #endif
  1675. #endregion
  1676. #region 运算符。
  1677. /// <summary>从 Json 到 Boolean 的隐式转换,判断 Json 对象可用。</summary>
  1678. public static implicit operator bool(Json json) => json != null && json.Available;
  1679. /// <summary>从 Json 到 String 的隐式转换,默认不缩进。</summary>
  1680. public static implicit operator string(Json json) => Export(json, false);
  1681. /// <summary>从 String 到 Json 的隐式转换。</summary>
  1682. /// <exception cref="System.Exception"></exception>
  1683. public static implicit operator Json(string text) => From(text);
  1684. #endregion
  1685. #region Statics
  1686. #region 创建实例。
  1687. /// <summary>创建新对象。</summary>
  1688. public static Json NewObject()
  1689. {
  1690. return new Json(new JObject());
  1691. }
  1692. /// <summary>创建新对象。</summary>
  1693. public static Json NewObject(Dictionary<string, string> dictionary)
  1694. {
  1695. var json = new Json(null);
  1696. json.Reset(dictionary);
  1697. return json;
  1698. }
  1699. /// <summary>创建新对象。</summary>
  1700. public static Json NewObject(TextSet dictionary)
  1701. {
  1702. var json = new Json(null);
  1703. json.Reset(dictionary);
  1704. return json;
  1705. }
  1706. /// <summary>创建新对象。</summary>
  1707. public static Json NewObject(ObjectSet<string> dictionary)
  1708. {
  1709. var json = new Json(null);
  1710. json.Reset(dictionary);
  1711. return json;
  1712. }
  1713. /// <summary>创建新对象。</summary>
  1714. public static Json NewArray()
  1715. {
  1716. return new Json(new JArray());
  1717. }
  1718. /// <summary>新建类型为 Property 的实例,值为 Null,失败时返回 Null。</summary>
  1719. /// <param name="name">Property 名称,不可为 Null。</param>
  1720. /// <exception cref="System.ArgumentNullException"></exception>
  1721. public static Json NewProperty(string name)
  1722. {
  1723. if (name == null)
  1724. {
  1725. if (AllowException) throw new ArgumentNullException("name", "参数无效。");
  1726. return null;
  1727. }
  1728. return new Json(new JProperty(name, null));
  1729. }
  1730. /// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
  1731. /// <param name="name">Property 名称,不可为 Null。</param>
  1732. /// <param name="value">Property 值。</param>
  1733. /// <exception cref="System.ArgumentNullException"></exception>
  1734. public static Json NewProperty(string name, string value)
  1735. {
  1736. if (name == null)
  1737. {
  1738. if (AllowException) throw new ArgumentNullException("name", "参数无效。");
  1739. return null;
  1740. }
  1741. return new Json(new JProperty(name, value));
  1742. }
  1743. /// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
  1744. /// <param name="name">Property 名称,不可为 Null。</param>
  1745. /// <param name="value">Property 值。</param>
  1746. /// <exception cref="System.ArgumentNullException"></exception>
  1747. public static Json NewProperty(string name, bool value)
  1748. {
  1749. if (name == null)
  1750. {
  1751. if (AllowException) throw new ArgumentNullException("name", "参数无效。");
  1752. return null;
  1753. }
  1754. return new Json(new JProperty(name, value));
  1755. }
  1756. /// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
  1757. /// <param name="name">Property 名称,不可为 Null。</param>
  1758. /// <param name="value">Property 值。</param>
  1759. /// <exception cref="System.ArgumentNullException"></exception>
  1760. public static Json NewProperty(string name, int value)
  1761. {
  1762. if (name == null)
  1763. {
  1764. if (AllowException) throw new ArgumentNullException("name", "参数无效。");
  1765. return null;
  1766. }
  1767. return new Json(new JProperty(name, value));
  1768. }
  1769. /// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
  1770. /// <param name="name">Property 名称,不可为 Null。</param>
  1771. /// <param name="value">Property 值。</param>
  1772. /// <exception cref="System.ArgumentNullException"></exception>
  1773. public static Json NewProperty(string name, long value)
  1774. {
  1775. if (name == null)
  1776. {
  1777. if (AllowException) throw new ArgumentNullException("name", "参数无效。");
  1778. return null;
  1779. }
  1780. return new Json(new JProperty(name, value));
  1781. }
  1782. /// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
  1783. /// <param name="name">Property 名称,不可为 Null。</param>
  1784. /// <param name="value">Property 值。</param>
  1785. /// <exception cref="System.ArgumentNullException"></exception>
  1786. public static Json NewProperty(string name, float value)
  1787. {
  1788. if (name == null)
  1789. {
  1790. if (AllowException) throw new ArgumentNullException("name", "参数无效。");
  1791. return null;
  1792. }
  1793. return new Json(new JProperty(name, value));
  1794. }
  1795. /// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
  1796. /// <param name="name">Property 名称,不可为 Null。</param>
  1797. /// <param name="value">Property 值。</param>
  1798. /// <exception cref="System.ArgumentNullException"></exception>
  1799. public static Json NewProperty(string name, double value)
  1800. {
  1801. if (name == null)
  1802. {
  1803. if (AllowException) throw new ArgumentNullException("name", "参数无效。");
  1804. return null;
  1805. }
  1806. return new Json(new JProperty(name, value));
  1807. }
  1808. /// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
  1809. /// <param name="name">Property 名称,不可为 Null。</param>
  1810. /// <param name="value">Property 值。</param>
  1811. /// <exception cref="System.ArgumentNullException"></exception>
  1812. public static Json NewProperty(string name, decimal value)
  1813. {
  1814. if (name == null)
  1815. {
  1816. if (AllowException) throw new ArgumentNullException("name", "参数无效。");
  1817. return null;
  1818. }
  1819. return new Json(new JProperty(name, value));
  1820. }
  1821. /// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
  1822. /// <param name="name">Property 名称,不可为 Null。</param>
  1823. /// <param name="value">Property 值。</param>
  1824. /// <exception cref="System.ArgumentNullException"></exception>
  1825. public static Json NewProperty(string name, Json value)
  1826. {
  1827. if (name == null)
  1828. {
  1829. if (AllowException) throw new ArgumentNullException("name", "参数无效。");
  1830. return null;
  1831. }
  1832. if (value == null) return new Json(new JProperty(name, null));
  1833. return new Json(new JProperty(name, null));
  1834. }
  1835. #endregion
  1836. /// <summary>格式化 Json 文本。</summary>
  1837. public static string Format(string text)
  1838. {
  1839. if (text == null || text == "") return "";
  1840. try
  1841. {
  1842. var serializer = new Newtonsoft.Json.JsonSerializer();
  1843. var tr = (System.IO.TextReader)(new System.IO.StringReader(text));
  1844. var jtr = new Newtonsoft.Json.JsonTextReader(tr);
  1845. var obj = serializer.Deserialize(jtr);
  1846. if (obj != null)
  1847. {
  1848. var textWriter = new System.IO.StringWriter();
  1849. var jsonWriter = new Newtonsoft.Json.JsonTextWriter(textWriter)
  1850. {
  1851. Formatting = Newtonsoft.Json.Formatting.Indented,
  1852. Indentation = 4,
  1853. IndentChar = ' '
  1854. };
  1855. serializer.Serialize(jsonWriter, obj);
  1856. return textWriter.ToString();
  1857. }
  1858. else
  1859. {
  1860. return text;
  1861. }
  1862. }
  1863. catch
  1864. {
  1865. return text ?? "";
  1866. }
  1867. }
  1868. /// <summary>重命名属性名称。</summary>
  1869. public static Json Rename(Json json, Func<string, string> renamer)
  1870. {
  1871. if (json == null) return null;
  1872. switch (json.TokenType)
  1873. {
  1874. case JTokenType.Array:
  1875. var items = json.GetItems();
  1876. foreach (var i in items) Rename(i, renamer);
  1877. break;
  1878. case JTokenType.Object:
  1879. var properties = json.GetProperties();
  1880. foreach (var i in properties)
  1881. {
  1882. var name = i._jproperty.Name;
  1883. var value = i._jproperty.Value;
  1884. if (!string.IsNullOrEmpty(name))
  1885. {
  1886. var newName = renamer(name);
  1887. var newValue = Rename(new Json(value), renamer)?._jtoken;
  1888. if (name != newName)
  1889. {
  1890. i.Remove();
  1891. json._jobject.Add(newName, newValue ?? value);
  1892. }
  1893. }
  1894. }
  1895. break;
  1896. }
  1897. return json;
  1898. }
  1899. /// <summary>设置属性名称为小写。</summary>
  1900. public static Json Lower(Json json) => Rename(json, (old) => old.Lower());
  1901. /// <summary>设置属性名称为驼峰形式。</summary>
  1902. public static Json Camel(Json json) => Rename(json, (old) => TextUtility.Camel(old));
  1903. private static bool CanSerialize(Type type, bool inherit = false)
  1904. {
  1905. if (type == null) return false;
  1906. if (type.BaseType.Equals(typeof(Array))) return true;
  1907. var interfaces = type.GetInterfaces();
  1908. foreach (var i in interfaces)
  1909. {
  1910. if (i.Equals(typeof(IList))) return true;
  1911. }
  1912. if (type.Equals(typeof(object))) return false;
  1913. var sas = type.GetCustomAttributes(typeof(SerializableAttribute), inherit);
  1914. if (sas != null && sas.Length > 0) return true;
  1915. var tas = type.GetCustomAttributes(typeof(Source.TableAttribute), inherit);
  1916. if (tas != null && tas.Length > 0) return true;
  1917. return false;
  1918. }
  1919. /// <summary>序列化指定对象为 JSON 字符串。</summary>
  1920. /// <exception cref="Exception"></exception>
  1921. public static string SerializeObject(object @object, Type type = null, bool indented = false, string onError = null) => JsonConvert.SerializeObject(@object, type, indented ? Formatting.Indented : Formatting.None, null);
  1922. /// <summary>反序列化 JSON 字符串为指定的类型。</summary>
  1923. /// <exception cref="Exception"></exception>
  1924. public static T DeserializeObject<T>(string json) => (T)DeserializeObject(json, typeof(T));
  1925. /// <summary>反序列化 JSON 字符串为指定的类型。</summary>
  1926. /// <exception cref="Exception"></exception>
  1927. public static object DeserializeObject(string json, Type type = null) => JsonConvert.DeserializeObject(json, type, (JsonSerializerSettings)null);
  1928. #if !NET20
  1929. /// <summary>反序列化 JSON 字符串为指定的类型列表。</summary>
  1930. /// <typeparam name="T">要反序列化的类型。</typeparam>
  1931. /// <param name="json">将要反序列化的 JSON 字符串。</param>
  1932. /// <param name="returnNullOnError">发生错误时返回 NULL 值,设置为 FALSE 时返回空 List&lt;<typeparamref name="T"/>&gt; 对象。</param>
  1933. /// <returns></returns>
  1934. public static T[] DeserializeArray<T>(string json, bool returnNullOnError = false) where T : class
  1935. {
  1936. try
  1937. {
  1938. var serializer = new JsonSerializer();
  1939. var @object = null as object;
  1940. using (var sr = new StringReader(json))
  1941. {
  1942. using (var jtr = new JsonTextReader(sr))
  1943. {
  1944. @object = serializer.Deserialize(jtr, typeof(T[]));
  1945. }
  1946. }
  1947. return (@object as T[]) ?? new T[0];
  1948. }
  1949. catch { return returnNullOnError ? null : new T[0]; }
  1950. }
  1951. #endif
  1952. #endregion
  1953. }
  1954. }