using Apewer;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
#if !NET20
using System.Dynamic;
#endif
using System.Reflection;
using System.Text;
namespace Apewer
{
/// Json。
[Serializable]
public class Json
{
#region 配置。
[NonSerialized]
private static bool _throw = false;
[NonSerialized]
private static bool _recursively = 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; } }
#endregion
#region 构造。
#region 基础。
[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;
#endregion
#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 = Parse(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 = Parse(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
{
var property = GetProperty(name);
if (property == null) return "";
return property.ToString();
}
set
{
SetProperty(name, 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 JToken) return new Json((JToken)_jvalue.Value);
else return _jvalue.Value;
}
if (_jproperty != null)
{
if (_jproperty.Value == null) return null;
if (_jproperty.Value is JToken) return new Json((JToken)_jproperty.Value);
else return _jproperty.Value;
}
return null;
}
}
/// 实例无效。
public bool IsNull { get { return _jtoken == null; } }
#endregion
#region Private Get
private List PrivateGetProperties { get { return GetProperties(); } }
private List PrivateGetValues { get { return GetValues(); } }
private List PrivateGetObjects { get { return GetObjects(); } }
private List PrivateGetItems { get { return GetItems(); } }
#endregion
#region Object : Get/Set
/// 获取所有类型为 Property 的子项。
public List GetProperties()
{
var list = new List();
if (_jobject != null)
{
var children = _jobject.Children();
foreach (var child in children)
{
var json = new Json(child);
list.Add(json);
}
}
return list;
}
/// 当前实例类型为 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 List GetValues()
{
var list = new List();
if (_jarray != null)
{
var children = _jarray.Children();
foreach (var child in children)
{
var json = new Json(child);
list.Add(json);
}
}
return list;
}
/// 获取所有类型为 Object 的子项。
public List GetObjects()
{
var list = new List();
if (_jarray != null)
{
var children = _jarray.Children();
foreach (var child in children)
{
var json = new Json(child);
list.Add(json);
}
}
return list;
}
/// 获取 Array 中的所有元素。
public List GetItems()
{
var list = new List();
if (_jarray != null)
{
var children = _jarray.Children();
foreach (var child in children)
{
var json = new Json(child);
list.Add(json);
}
}
return list;
}
/// 当前实例类型为 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;
}
}
#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 From Text
/// 从 String 到 Json 的隐式转换。
///
public static implicit operator Json(string text)
{
return Parse(text);
}
/// 解析文本为 Json 对象,失败时返回 Null。
///
public static Json Parse(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 From Entity
/// 解析实现 IList 的对象为 Json 对象,失败时返回 Null。
/// 将要解析的对象。
/// 在 Json 中将属性名称转换为小写。
/// 限制 Json 层级深度,当值小于零时将不限制深度。
/// 强制解析属性,忽略 Serializable 特性。
public static Json Parse(IList entity, bool lower = false, int depth = -1, bool force = false)
{
if (entity == null) return null;
var recursive = new List