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.

2279 lines
89 KiB

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