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.

2584 lines
101 KiB

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