using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
#if !NET20
using System.Dynamic;
using System.IO;
#endif
using System.Reflection;
using static Apewer.NumberUtility;
using static Apewer.RuntimeUtility;
namespace Apewer
{
/// Json。
[Serializable]
public sealed class Json
#if !NET20
: DynamicObject
#endif
{
#region 配置。
[NonSerialized]
private static bool _throw = false;
[NonSerialized]
private static bool _recursively = true;
[NonSerialized]
private static bool _forceall = true;
/// 允许抛出 Exception,默认为不允许。
public static bool AllowException { get { return _throw; } set { _throw = value; } }
/// 当存在递归引用时候包含递归项。指定为 True 时递归项为 Null 值,指定为 False 时不包含递归项。默认值:False。
public static bool AllowRecursively { get { return _recursively; } set { _recursively = value; } }
/// 将所有类型视为拥有 特性。
/// 默认值:FALSE。
public static bool ForceAll { get => _forceall; set => _forceall = value; }
#endregion
#region 消息
private const string ValueIsNotSupported = "指定的值类型不受支持";
private const string IsNotJsonObject = "当前实例不是 Json 对象。";
private const string IsNotJsonArray = "当前实例不是 Json 数组。";
private const string InvalidIndex = "未指定有效的索引。";
private const string IndexLessZero = "指定的索引小于 0,无效。";
private const string IndexGraterMax = "指定的索引超出了最大值,无效。";
private const string IndexGraterCount = "指定的索引超出了数量,无效。";
#endregion
#region JToken
[NonSerialized]
private JToken _jtoken = null;
[NonSerialized]
private JArray _jarray = null;
[NonSerialized]
private JObject _jobject = null;
[NonSerialized]
private JProperty _jproperty = null;
[NonSerialized]
private JValue _jvalue = null;
static JToken ToJToken(object value)
{
if (value == null) return new JValue(null, JTokenType.Null);
var type = value.GetType();
if (RuntimeUtility.IsNullableType(type)) value = RuntimeUtility.GetNullableValue(value);
if (value == null) return new JValue(null, JTokenType.Null);
if (value is Json json) return json?._jtoken ?? new JValue(null, JTokenType.Null);
if (value is DateTime dt) return new JValue(SerializeDateTime(dt));
if (value is string) return new JValue(value);
if (value is bool) return new JValue(value);
if (value is byte) return new JValue(value);
if (value is sbyte) return new JValue(value);
if (value is short) return new JValue(value);
if (value is ushort) return new JValue(value);
if (value is int) return new JValue(value);
if (value is uint) return new JValue(value);
if (value is long) return new JValue(value);
if (value is ulong uint64) return (uint64 > int.MaxValue) ? new JValue(uint64.ToString()) : new JValue(Convert.ToInt64(uint64));
if (value is float) return new JValue(value);
if (value is double) return new JValue(value);
if (value is decimal) return new JValue(value);
var from = From(value);
if (from != null) return from._jtoken;
throw new ArgumentException(ValueIsNotSupported);
}
static object ParseJToken(JToken jtoken)
{
if (jtoken == null) return null;
if (jtoken is JValue jvalue) return jvalue.Value;
if (jtoken is JObject) return new Json(jtoken);
if (jtoken is JArray) return new Json(jtoken);
if (jtoken is JProperty jproperty)
{
var value = jproperty.Value;
if (value == null) return null;
return ParseJToken(value);
}
throw new InvalidOperationException($"Json 类型 {jtoken.Type} 不支持解析。");
}
#endregion
#region 构造。
#region Reset
/// 重置当前对象为空。
public void Reset()
{
Construct();
}
/// 使用指定的文本重置当前对象。
public bool Reset(string json)
{
Construct();
if (json == null)
{
if (AllowException) throw new ArgumentNullException("json", "参数无效。");
return false;
}
var parsed = From(json);
if (parsed == null) return false;
Construct(parsed._jtoken);
return true;
}
/// 使用指定的对象重置当前对象。
///
///
public bool Reset(Json json)
{
Construct();
if (json == null)
{
if (AllowException) throw new ArgumentNullException("json", "参数无效。");
return false;
}
var parsed = From(json.ToString());
if (parsed == null) return false;
Construct(parsed._jtoken);
return true;
}
/// 使用指定的字典对象重置当前对象。
///
///
public bool Reset(Dictionary dictionary)
{
Construct();
if (dictionary == null)
{
if (AllowException) throw new ArgumentNullException("dictionary", "参数无效。");
return false;
}
var json = NewObject();
foreach (var item in dictionary) json[item.Key] = item.Value;
Construct(json._jtoken);
return true;
}
/// 使用指定的文本字典对象重置当前对象。
///
///
public bool Reset(TextSet dictionary)
{
Construct();
if (dictionary == null)
{
if (AllowException) throw new ArgumentNullException("dictionary", "参数无效。");
return false;
}
return Reset(dictionary.Origin);
}
/// 使用指定的文本字典对象重置当前对象。
///
///
public bool Reset(ObjectSet dictionary)
{
Construct();
if (dictionary == null)
{
if (AllowException) throw new ArgumentNullException("dictionary", "参数无效。");
return false;
}
return Reset(dictionary.Origin);
}
#endregion
private void Construct(JToken jtoken = null)
{
_jtoken = jtoken;
_jarray = null;
_jobject = null;
_jproperty = null;
_jvalue = null;
if (_jtoken != null)
{
if (_jtoken is JArray) _jarray = (JArray)_jtoken;
if (_jtoken is JObject) _jobject = (JObject)_jtoken;
if (_jtoken is JProperty) _jproperty = (JProperty)_jtoken;
if (_jtoken is JValue) _jvalue = (JValue)_jtoken;
}
}
private Json(JToken jtoken)
{
Construct(jtoken);
}
/// 创建 Json Object 实例。
public Json()
{
Construct(new JObject());
}
#endregion
#region 属性。
/// 用于兼容 SimpleJson 的操作。
public string this[string name] { get => GetProperty(name)?.ToString() ?? ""; set => SetProperty(name, value ?? ""); }
/// 获取或设置数组的元素。
public object this[int index] { get => GetItem(index); set => SetItem(index, value); }
private JTokenType TokenType
{
get
{
if (_jtoken == null) return JTokenType.None;
else return _jtoken.Type;
//if (_jtoken == null) return 0;
//switch (_jtoken.Type)
//{
// case JTokenType.None: return 0;
// case JTokenType.Object: return 1;
// case JTokenType.Array: return 2;
// case JTokenType.Constructor: return 3;
// case JTokenType.Property: return 4;
// case JTokenType.Comment: return 5;
// case JTokenType.Integer: return 6;
// case JTokenType.Float: return 7;
// case JTokenType.String: return 8;
// case JTokenType.Boolean: return 9;
// case JTokenType.Null: return 10;
// case JTokenType.Undefined: return 11;
// case JTokenType.Date: return 12;
// case JTokenType.Raw: return 13;
// case JTokenType.Bytes: return 14;
// case JTokenType.Guid: return 15;
// case JTokenType.Uri: return 16;
// case JTokenType.TimeSpan: return 17;
// default: return 0;
//}
}
}
///
/// 获取当前实例的类型。可能的类型:
/// None Object Array Constructor Property Comment Integer Float String
/// Boolean Null Undefined Date Raw Bytes Guid Uri TimeSpan
///
public string Type { get { return TokenType.ToString(); } }
/// 实例有效。
public bool Available { get { return _jtoken != null && TokenType != JTokenType.None; } }
/// 获取当前实例的值,当为 Json 格式时缩进。
public string Lucid { get { return ToString(true); } }
/// 获取当前实例的值,当为 Json 格式时不缩进。
public string Text { get { return ToString(false); } }
/// 当前实例类型为 Property 时,获取名称。
public string Name
{
get { return _jproperty == null ? null : _jproperty.Name; }
}
/// 获取值。
public object Value
{
get
{
if (_jvalue != null)
{
if (_jvalue.Value == null) return null;
if (_jvalue.Value is JValue jvalue) return jvalue.Value;
if (_jvalue.Value is JToken jtoken) return new Json(jtoken);
else return _jvalue.Value;
}
if (_jproperty != null)
{
if (_jproperty.Value == null) return null;
if (_jproperty.Value is JValue jvalue) return jvalue.Value;
if (_jproperty.Value is JToken jtoken) return new Json(jtoken);
else return _jproperty.Value;
}
return null;
}
}
/// 实例无效。
public bool IsNull { get { return _jtoken == null; } }
#endregion
#region Private Get
private Json[] PrivateGetProperties { get { return GetProperties(); } }
private Json[] PrivateGetValues { get { return GetValues(); } }
private Json[] PrivateGetObjects { get { return GetObjects(); } }
private Json[] PrivateGetItems { get { return GetItems(); } }
#endregion
#region Object : Get/Set
/// 获取所有类型为 Property 的子项。
public Json[] GetProperties()
{
var ab = new ArrayBuilder();
if (_jobject != null)
{
var children = _jobject.Children();
foreach (var child in children)
{
var json = new Json(child);
ab.Add(json);
}
}
return ab.Export();
}
/// 当前实例类型为 Object 时搜索属性,失败时返回 Null。
/// 将要搜索的属性名称,不可为 Null。
///
///
public Json GetProperty(string name)
{
if (_jobject == null || TokenType != JTokenType.Object)
{
if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
return null;
}
if (name == null)
{
if (_throw) throw new ArgumentNullException("name", "参数无效。");
return null;
}
var children = _jtoken.Children();
foreach (var child in children)
{
if (child.Name == name)
{
var json = new Json(child.Value);
return json;
}
}
return null;
}
/// 当前实例类型为 Object 时添加属性,值为 Null,已存在的属性将被替换。
/// 将要添加的属性名称,不可为 Null。
///
///
public bool SetProperty(string name)
{
if (_jobject == null || TokenType != JTokenType.Object)
{
if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
return false;
}
if (name == null)
{
if (_throw) throw new ArgumentNullException("name", "参数无效。");
return false;
}
var children = _jobject.Children();
foreach (var child in children)
{
if (child.Name == name)
{
_jobject.Remove(name);
break;
}
}
_jobject.Add(name, null);
return true;
}
/// 当前实例类型为 Object 时添加属性,已存在的属性将被替换。
/// 将要添加的属性。
///
///
///
public bool SetProperty(Json property)
{
if (_jobject == null || TokenType != JTokenType.Object)
{
if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
return false;
}
if (property == null)
{
if (_throw) throw new ArgumentNullException("property", "参数无效。");
return false;
}
if (property._jproperty == null || property.TokenType != JTokenType.Property)
{
if (_throw) throw new ArgumentException("property", "将要设置的属性无效。");
return false;
}
var name = property._jproperty.Name;
var children = _jobject.Children();
foreach (var child in children)
{
if (child.Name == name)
{
_jobject.Remove(name);
break;
}
}
_jobject.Add(name, property._jtoken);
return true;
}
/// 当前实例类型为 Object 时添加属性,已存在的属性将被替换。
/// 将要添加的属性名称,不可为 Null。
/// 将要添加的属性值。
///
///
public bool SetProperty(string name, bool value)
{
if (_jobject == null || TokenType != JTokenType.Object)
{
if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
return false;
}
if (name == null)
{
if (_throw) throw new ArgumentNullException("name", "参数无效。");
return false;
}
var children = _jobject.Children();
foreach (var child in children)
{
if (child.Name == name)
{
_jobject.Remove(name);
break;
}
}
_jobject.Add(name, value);
return true;
}
/// 当前实例类型为 Object 时添加属性,已存在的属性将被替换。
/// 将要添加的属性名称,不可为 Null。
/// 将要添加的属性值。
///
///
public bool SetProperty(string name, string value)
{
if (_jobject == null || TokenType != JTokenType.Object)
{
if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
return false;
}
if (name == null)
{
if (_throw) throw new ArgumentNullException("name", "参数无效。");
return false;
}
var children = _jobject.Children();
foreach (var child in children)
{
if (child.Name == name)
{
_jobject.Remove(name);
break;
}
}
_jobject.Add(name, value);
return true;
}
/// 当前实例类型为 Object 时添加属性,已存在的属性将被替换。
/// 将要添加的属性名称,不可为 Null。
/// 将要添加的属性值。
///
///
public bool SetProperty(string name, int value)
{
if (_jobject == null || TokenType != JTokenType.Object)
{
if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
return false;
}
if (name == null)
{
if (_throw) throw new ArgumentNullException("name", "参数无效。");
return false;
}
var children = _jobject.Children();
foreach (var child in children)
{
if (child.Name == name)
{
_jobject.Remove(name);
break;
}
}
_jobject.Add(name, value);
return true;
}
/// 当前实例类型为 Object 时添加属性,已存在的属性将被替换。
/// 将要添加的属性名称,不可为 Null。
/// 将要添加的属性值。
///
///
public bool SetProperty(string name, long value)
{
if (_jobject == null || TokenType != JTokenType.Object)
{
if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
return false;
}
if (name == null)
{
if (_throw) throw new ArgumentNullException("name", "参数无效。");
return false;
}
var children = _jobject.Children();
foreach (var child in children)
{
if (child.Name == name)
{
_jobject.Remove(name);
break;
}
}
_jobject.Add(name, value);
return true;
}
/// 当前实例类型为 Object 时添加属性,已存在的属性将被替换。
/// 将要添加的属性名称,不可为 Null。
/// 将要添加的属性值。
///
///
public bool SetProperty(string name, float value)
{
if (_jobject == null || TokenType != JTokenType.Object)
{
if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
return false;
}
if (name == null)
{
if (_throw) throw new ArgumentNullException("name", "参数无效。");
return false;
}
var children = _jobject.Children();
foreach (var child in children)
{
if (child.Name == name)
{
_jobject.Remove(name);
break;
}
}
_jobject.Add(name, value);
return true;
}
/// 当前实例类型为 Object 时添加属性,已存在的属性将被替换。
/// 将要添加的属性名称,不可为 Null。
/// 将要添加的属性值。
///
///
public bool SetProperty(string name, double value)
{
if (_jobject == null || TokenType != JTokenType.Object)
{
if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
return false;
}
if (name == null)
{
if (_throw) throw new ArgumentNullException("name", "参数无效。");
return false;
}
var children = _jobject.Children();
foreach (var child in children)
{
if (child.Name == name)
{
_jobject.Remove(name);
break;
}
}
_jobject.Add(name, value);
return true;
}
/// 当前实例类型为 Object 时添加属性,已存在的属性将被替换。
/// 将要添加的属性名称,不可为 Null。
/// 将要添加的属性值。
///
///
public bool SetProperty(string name, decimal value)
{
if (_jobject == null || TokenType != JTokenType.Object)
{
if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
return false;
}
if (name == null)
{
if (_throw) throw new ArgumentNullException("name", "参数无效。");
return false;
}
var children = _jobject.Children();
foreach (var child in children)
{
if (child.Name == name)
{
_jobject.Remove(name);
break;
}
}
_jobject.Add(name, value);
return true;
}
/// 当前实例类型为 Object 时添加属性,已存在的属性将被替换。
/// 将要添加的属性名称,不可为 Null。
/// 将要添加的属性值。
///
///
///
public bool SetProperty(string name, Json value)
{
if (_jobject == null || TokenType != JTokenType.Object)
{
if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
return false;
}
if (name == null)
{
if (_throw) throw new ArgumentNullException("name", "参数无效。");
return false;
}
var children = _jobject.Children();
foreach (var child in children)
{
if (child.Name == name)
{
_jobject.Remove(name);
break;
}
}
if (value == null)
{
_jobject.Add(name, null);
}
else
{
if (value._jtoken == null)
{
_jobject.Add(name, null);
}
else
{
_jobject.Add(name, value._jtoken);
}
}
return true;
}
#endregion
#region Array
/// 获取所有类型为 Value 的子项。
public Json[] GetValues()
{
var ab = new ArrayBuilder();
if (_jarray != null)
{
var children = _jarray.Children();
foreach (var child in children)
{
var json = new Json(child);
ab.Add(json);
}
}
return ab.Export();
}
/// 获取所有类型为 Object 的子项。
public Json[] GetObjects()
{
var ab = new ArrayBuilder();
if (_jarray != null)
{
var children = _jarray.Children();
foreach (var child in children)
{
var json = new Json(child);
ab.Add(json);
}
}
return ab.Export();
}
/// 获取 Array 中的所有元素。
public Json[] GetItems()
{
var ab = new ArrayBuilder();
if (_jarray != null)
{
var children = _jarray.Children();
foreach (var child in children)
{
var json = new Json(child);
ab.Add(json);
}
}
return ab.Export();
}
/// 当前实例类型为 Array 时添加 Null 元素。
///
public bool AddItem()
{
if (_jarray == null || TokenType != JTokenType.Array)
{
if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
return false;
}
_jarray.Add(JValue.CreateNull());
return true;
}
/// 当前实例类型为 Array 时添加元素。
/// 将要添加的元素。
///
public bool AddItem(Json json)
{
if (json == null)
{
return AddItem();
}
if (_jarray == null || TokenType != JTokenType.Array)
{
if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
return false;
}
if (json._jtoken == null || json.TokenType == JTokenType.None)
{
if (_throw) throw new ArgumentException("json", "将要设置的元素无效。");
return false;
}
_jarray.Add(json._jtoken);
return true;
}
/// 当前实例类型为 Array 时添加元素。
/// 将要添加的元素。
///
public bool AddItem(string value)
{
if (_jarray == null || TokenType != JTokenType.Array)
{
if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
return false;
}
_jarray.Add(value ?? "");
return true;
}
/// 当前实例类型为 Array 时添加元素。
/// 将要添加的元素。
///
public bool AddItem(bool value)
{
if (_jarray == null || TokenType != JTokenType.Array)
{
if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
return false;
}
_jarray.Add(value);
return true;
}
/// 当前实例类型为 Array 时添加元素。
/// 将要添加的元素。
///
public bool AddItem(int value)
{
if (_jarray == null || TokenType != JTokenType.Array)
{
if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
return false;
}
_jarray.Add(value);
return true;
}
/// 当前实例类型为 Array 时添加元素。
/// 将要添加的元素。
///
public bool AddItem(long value)
{
if (_jarray == null || TokenType != JTokenType.Array)
{
if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
return false;
}
_jarray.Add(value);
return true;
}
/// 当前实例类型为 Array 时添加元素。
/// 将要添加的元素。
///
public bool AddItem(float value)
{
if (_jarray == null || TokenType != JTokenType.Array)
{
if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
return false;
}
_jarray.Add(value);
return true;
}
/// 当前实例类型为 Array 时添加元素。
/// 将要添加的元素。
///
public bool AddItem(double value)
{
if (_jarray == null || TokenType != JTokenType.Array)
{
if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
return false;
}
_jarray.Add(value);
return true;
}
/// 当前实例类型为 Array 时添加元素。
/// 将要添加的元素。
///
public bool AddItem(decimal value)
{
if (_jarray == null || TokenType != JTokenType.Array)
{
if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
return false;
}
_jarray.Add(value);
return true;
}
/// 从 Parent 中移除。
///
///
public bool Remove()
{
if (_jtoken == null) return false;
if (_jtoken.Parent == null)
{
if (_throw) throw new InvalidOperationException("Parent 对象丢失。");
return false;
}
try
{
_jtoken.Remove();
return true;
}
catch (Exception exception)
{
if (_throw) throw exception;
return false;
}
}
/// 获取数组的元素。
///
///
public object GetItem(int index)
{
if (!IsArray) throw new InvalidOperationException(IsNotJsonArray);
if (index < 0) throw new ArgumentOutOfRangeException(nameof(index), IndexLessZero);
var jarray = _jtoken as JArray;
if (index >= jarray.Count) throw new ArgumentOutOfRangeException(nameof(index), IndexGraterCount);
var item = jarray[index];
return ParseJToken(item);
}
/// 设置数组的元素。
///
///
///
public void SetItem(int index, object value)
{
if (!IsArray) throw new InvalidOperationException(IsNotJsonArray);
if (index < 0) throw new ArgumentOutOfRangeException(nameof(index), IndexLessZero);
var jarray = _jtoken as JArray;
while (jarray.Count < index + 1) jarray.Add(null);
var jtoken = ToJToken(value);
jarray.SetItem(index, jtoken);
}
#endregion
#region Property
/// Json 对象实例为空。
public bool IsNone { get { return TokenType == JTokenType.None; } }
/// Json 对象为 Object 实例。
public bool IsObject { get { return TokenType == JTokenType.Object; } }
/// Json 对象为 Array 实例。
public bool IsArray { get { return TokenType == JTokenType.Array; } }
/// Json 对象为 Property 实例。
public bool IsProperty { get { return TokenType == JTokenType.Property; } }
/// Json 对象为 String 实例。
public bool IsString { get { return TokenType == JTokenType.String; } }
/// 当前实例类型为 Property 时设置 Null 值。
///
public bool SetValue()
{
var available = _jproperty != null && TokenType == JTokenType.Property;
if (!available)
{
if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
return false;
}
_jproperty.Value = JValue.CreateNull();
return true;
}
/// 当前实例类型为 Property 时设置值。
/// 将要设置的值。
///
public bool SetValue(Json value)
{
var available = _jproperty != null && TokenType == JTokenType.Property;
if (!available)
{
if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
return false;
}
if (value == null)
{
_jproperty.Value = JValue.CreateNull();
return true;
}
if (value._jtoken == null || value.TokenType == JTokenType.None)
{
_jproperty.Value = JValue.CreateNull();
return true;
}
_jproperty.Value = new JValue(value._jtoken);
return true;
}
/// 当前实例类型为 Property 时设置值。
/// 将要设置的值。
///
public bool SetValue(string value)
{
var available = _jproperty != null && TokenType == JTokenType.Property;
if (!available)
{
if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
return false;
}
_jproperty.Value = value == null ? JValue.CreateNull() : JValue.CreateString(value);
return true;
}
/// 当前实例类型为 Property 时设置值。
/// 将要设置的值。
///
public bool SetValue(bool value)
{
var available = _jproperty != null && TokenType == JTokenType.Property;
if (!available)
{
if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
return false;
}
_jproperty.Value = new JValue(value);
return true;
}
/// 当前实例类型为 Property 时设置值。
/// 将要设置的值。
///
public bool SetValue(int value)
{
var available = _jproperty != null && TokenType == JTokenType.Property;
if (!available)
{
if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
return false;
}
_jproperty.Value = new JValue(value);
return true;
}
/// 当前实例类型为 Property 时设置值。
/// 将要设置的值。
///
public bool SetValue(long value)
{
var available = _jproperty != null && TokenType == JTokenType.Property;
if (!available)
{
if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
return false;
}
_jproperty.Value = new JValue(value);
return true;
}
/// 当前实例类型为 Property 时设置值。
/// 将要设置的值。
///
public bool SetValue(float value)
{
var available = _jproperty != null && TokenType == JTokenType.Property;
if (!available)
{
if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
return false;
}
_jproperty.Value = new JValue(value);
return true;
}
/// 当前实例类型为 Property 时设置值。
/// 将要设置的值。
///
public bool SetValue(double value)
{
var available = _jproperty != null && TokenType == JTokenType.Property;
if (!available)
{
if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
return false;
}
_jproperty.Value = new JValue(value);
return true;
}
/// 当前实例类型为 Property 时设置值。
/// 将要设置的值。
///
public bool SetValue(decimal value)
{
var available = _jproperty != null && TokenType == JTokenType.Property;
if (!available)
{
if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
return false;
}
_jproperty.Value = new JValue(value);
return true;
}
#endregion
#region Import / Export
#region String -> Json
/// 解析文本为 Json 对象,失败时返回 Null。
///
public static Json From(string text)
{
try
{
var jtoken = JToken.Parse(text);
var json = new Json(jtoken);
return json;
}
catch (Exception exception)
{
if (AllowException) throw exception;
return null;
}
}
#endregion
#region Object -> Json
/// 解析实现 IList 的对象为 Json 对象,失败时返回 Null。
/// 将要解析的对象。
/// 在 Json 中将属性名称转换为小写。
/// 限制 Json 层级深度,当值小于零时将不限制深度。
/// 强制解析属性,忽略 Serializable 特性。
public static Json From(IList entity, bool lower = false, int depth = -1, bool force = false)
{
if (entity == null) return null;
var recursive = new object[] { entity };
return From(entity, lower, recursive, depth, force);
}
/// 解析实现 IDictionary 的对象为 Json 对象,失败时返回 Null。
/// 将要解析的对象。
/// 在 Json 中将属性名称转换为小写。
/// 限制 Json 层级深度,当值小于零时将不限制深度。
/// 强制解析属性,忽略 Serializable 特性。
public static Json From(IDictionary entity, bool lower = false, int depth = -1, bool force = false)
{
if (entity == null) return null;
var recursive = new object[] { entity };
return From(entity, lower, recursive, depth, force);
}
///
/// 解析对象为 Json 对象,包含所有公共属性,失败时返回 Null。
/// String 对象将解析文本;Json 对象将返回实例;String 对象将解析文本;实现 IDictionary 或 IList 的对象将解析内容。
///
/// 将要解析的对象。
/// 在 Json 中将属性名称转换为小写。
/// 限制 Json 层级深度,当值小于零时将不限制深度。
/// 强制解析属性,忽略 Serializable 特性。
///
public static Json From(object entity, bool lower = false, int depth = -1, bool force = false)
{
if (entity == null) return null;
var recursive = new object[] { entity };
return From(entity, lower, recursive, depth, force);
}
private static Json From(IList list, bool lower, object[] previous, int depth, bool force)
{
if (list == null) return null;
if (list is IToJson) return ((IToJson)list).ToJson();
var checker = list as IToJsonChecker;
var json = NewArray();
try
{
if (list is Array array)
{
if (array != null && array.Rank > 1)
{
ToJson(json, array, array.Rank, new int[0]);
return json;
}
}
foreach (var item in list)
{
// 由 IToJsonChecker 实现的方法检查是否包含元素。
if (checker != null && !checker.WithItemInJson(list, item)) continue;
var value = item;
// 检查递归引用。
var recursively = false;
foreach (var r in previous)
{
if (ReferenceEquals(r, value))
{
if (AllowRecursively) json.AddItem();
recursively = true;
break;
}
}
if (recursively) continue;
// value 是 null。
if (value.IsNull())
{
json.AddItem();
continue;
}
// 处理 Type 对象。
if (value.GetType().Equals(typeof(Type)) && (previous.Length > 2)) value = FullName((Type)value);
// 处理 Assembly 对象。
if (value.GetType().Equals(typeof(Assembly)) && (previous.Length > 2)) value = ((Assembly)value).FullName;
if (value == null) { json.AddItem(); }
else if (value is DateTime dt) { json.AddItem(SerializeDateTime(dt)); }
else if (value is bool) { json.AddItem((bool)value); }
else if (value is byte) { json.AddItem((byte)value); }
else if (value is sbyte) { json.AddItem((sbyte)value); }
else if (value is short) { json.AddItem((short)value); }
else if (value is ushort) { json.AddItem((ushort)value); }
else if (value is int) { json.AddItem((int)value); }
else if (value is uint) { json.AddItem((uint)value); }
else if (value is long) { json.AddItem((long)value); }
else if (value is ulong) { json.AddItem(value.ToString()); }
else if (value is float) { json.AddItem((float)value); }
else if (value is double) { json.AddItem((double)value); }
else if (value is decimal) { json.AddItem((decimal)value); }
else if (value is string) { json.AddItem((string)value); }
else if (value is Json) { json.AddItem(value as Json); }
else
{
if ((depth < 0) || (0 < depth && previous.Length < depth))
{
var recursive = new ArrayBuilder