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.

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