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.

1951 lines
73 KiB

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