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.

2091 lines
79 KiB

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