You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2091 lines
79 KiB
2091 lines
79 KiB
using Apewer;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
#if !NET20
|
|
using System.Dynamic;
|
|
using System.IO;
|
|
#endif
|
|
using System.Reflection;
|
|
using System.Runtime.Serialization;
|
|
using System.Text;
|
|
|
|
namespace Apewer
|
|
{
|
|
|
|
/// <summary>Json。</summary>
|
|
[Serializable]
|
|
public sealed class Json
|
|
#if !NET20
|
|
: DynamicObject
|
|
#endif
|
|
{
|
|
|
|
#region 配置。
|
|
|
|
[NonSerialized]
|
|
private static bool _throw = false;
|
|
|
|
[NonSerialized]
|
|
private static bool _recursively = true;
|
|
|
|
/// <summary>允许产生 Exception,默认为不允许。</summary>
|
|
public static bool AllowException { get { return _throw; } set { _throw = value; } }
|
|
|
|
/// <summary>当存在递归引用时候包含递归项。指定为 True 时递归项为 Null 值,指定为 False 时不包含递归项。默认值:False。</summary>
|
|
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
|
|
|
|
/// <summary>重置当前对象为空。</summary>
|
|
public void Reset()
|
|
{
|
|
Construct();
|
|
}
|
|
|
|
/// <summary>使用指定的文本重置当前对象。</summary>
|
|
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;
|
|
}
|
|
|
|
/// <summary>使用指定的对象重置当前对象。</summary>
|
|
/// <exception cref="System.Exception"></exception>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
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;
|
|
}
|
|
|
|
/// <summary>使用指定的字典对象重置当前对象。</summary>
|
|
/// <exception cref="System.Exception"></exception>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
public bool Reset(Dictionary<string, string> 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;
|
|
}
|
|
|
|
/// <summary>使用指定的文本字典对象重置当前对象。</summary>
|
|
/// <exception cref="System.Exception"></exception>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
public bool Reset(TextSet dictionary)
|
|
{
|
|
Construct();
|
|
if (dictionary == null)
|
|
{
|
|
if (AllowException) throw new ArgumentNullException("dictionary", "参数无效。");
|
|
return false;
|
|
}
|
|
return Reset(dictionary.Origin);
|
|
}
|
|
|
|
/// <summary>使用指定的文本字典对象重置当前对象。</summary>
|
|
/// <exception cref="System.Exception"></exception>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
public bool Reset(ObjectSet<string> 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);
|
|
}
|
|
|
|
/// <summary>创建 Json Object 实例。</summary>
|
|
public Json()
|
|
{
|
|
Construct(new JObject());
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 属性。
|
|
|
|
/// <summary>用于兼容 SimpleJson 的操作。</summary>
|
|
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;
|
|
//}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>获取当前实例的类型。可能的类型:</para>
|
|
/// <para>None Object Array Constructor Property Comment Integer Float String</para>
|
|
/// <para>Boolean Null Undefined Date Raw Bytes Guid Uri TimeSpan</para>
|
|
/// </summary>
|
|
public string Type { get { return TokenType.ToString(); } }
|
|
|
|
/// <summary>实例有效。</summary>
|
|
public
|
|
bool Available
|
|
{ get { return _jtoken != null && TokenType != JTokenType.None; } }
|
|
|
|
/// <summary>获取当前实例的值,当为 Json 格式时缩进。</summary>
|
|
public string Lucid { get { return ToString(true); } }
|
|
|
|
/// <summary>获取当前实例的值,当为 Json 格式时不缩进。</summary>
|
|
public string Text { get { return ToString(false); } }
|
|
|
|
/// <summary>当前实例类型为 Property 时,获取名称。</summary>
|
|
public string Name
|
|
{
|
|
get { return _jproperty == null ? null : _jproperty.Name; }
|
|
}
|
|
|
|
/// <summary>获取值。</summary>
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>实例无效。</summary>
|
|
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
|
|
|
|
/// <summary>获取所有类型为 Property 的子项。</summary>
|
|
public Json[] GetProperties()
|
|
{
|
|
var ab = new ArrayBuilder<Json>();
|
|
if (_jobject != null)
|
|
{
|
|
var children = _jobject.Children();
|
|
foreach (var child in children)
|
|
{
|
|
var json = new Json(child);
|
|
ab.Add(json);
|
|
}
|
|
}
|
|
return ab.Export();
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Object 时搜索属性,失败时返回 Null。</summary>
|
|
/// <param name="name">将要搜索的属性名称,不可为 Null。</param>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
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<JProperty>();
|
|
foreach (var child in children)
|
|
{
|
|
if (child.Name == name)
|
|
{
|
|
var json = new Json(child.Value);
|
|
return json;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Object 时添加属性,值为 Null,已存在的属性将被替换。</summary>
|
|
/// <param name="name">将要添加的属性名称,不可为 Null。</param>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
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<JProperty>();
|
|
foreach (var child in children)
|
|
{
|
|
if (child.Name == name)
|
|
{
|
|
_jobject.Remove(name);
|
|
break;
|
|
}
|
|
}
|
|
|
|
_jobject.Add(name, null);
|
|
return true;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
|
|
/// <param name="property">将要添加的属性。</param>
|
|
/// <exception cref="System.ArgumentException"></exception>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
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<JProperty>();
|
|
foreach (var child in children)
|
|
{
|
|
if (child.Name == name)
|
|
{
|
|
_jobject.Remove(name);
|
|
break;
|
|
}
|
|
}
|
|
|
|
_jobject.Add(name, property._jtoken);
|
|
return true;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
|
|
/// <param name="name">将要添加的属性名称,不可为 Null。</param>
|
|
/// <param name="value">将要添加的属性值。</param>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
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<JProperty>();
|
|
foreach (var child in children)
|
|
{
|
|
if (child.Name == name)
|
|
{
|
|
_jobject.Remove(name);
|
|
break;
|
|
}
|
|
}
|
|
|
|
_jobject.Add(name, value);
|
|
return true;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
|
|
/// <param name="name">将要添加的属性名称,不可为 Null。</param>
|
|
/// <param name="value">将要添加的属性值。</param>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
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<JProperty>();
|
|
foreach (var child in children)
|
|
{
|
|
if (child.Name == name)
|
|
{
|
|
_jobject.Remove(name);
|
|
break;
|
|
}
|
|
}
|
|
|
|
_jobject.Add(name, value);
|
|
return true;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
|
|
/// <param name="name">将要添加的属性名称,不可为 Null。</param>
|
|
/// <param name="value">将要添加的属性值。</param>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
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<JProperty>();
|
|
foreach (var child in children)
|
|
{
|
|
if (child.Name == name)
|
|
{
|
|
_jobject.Remove(name);
|
|
break;
|
|
}
|
|
}
|
|
|
|
_jobject.Add(name, value);
|
|
return true;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
|
|
/// <param name="name">将要添加的属性名称,不可为 Null。</param>
|
|
/// <param name="value">将要添加的属性值。</param>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
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<JProperty>();
|
|
foreach (var child in children)
|
|
{
|
|
if (child.Name == name)
|
|
{
|
|
_jobject.Remove(name);
|
|
break;
|
|
}
|
|
}
|
|
|
|
_jobject.Add(name, value);
|
|
return true;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
|
|
/// <param name="name">将要添加的属性名称,不可为 Null。</param>
|
|
/// <param name="value">将要添加的属性值。</param>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
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<JProperty>();
|
|
foreach (var child in children)
|
|
{
|
|
if (child.Name == name)
|
|
{
|
|
_jobject.Remove(name);
|
|
break;
|
|
}
|
|
}
|
|
|
|
_jobject.Add(name, value);
|
|
return true;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
|
|
/// <param name="name">将要添加的属性名称,不可为 Null。</param>
|
|
/// <param name="value">将要添加的属性值。</param>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
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<JProperty>();
|
|
foreach (var child in children)
|
|
{
|
|
if (child.Name == name)
|
|
{
|
|
_jobject.Remove(name);
|
|
break;
|
|
}
|
|
}
|
|
|
|
_jobject.Add(name, value);
|
|
return true;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
|
|
/// <param name="name">将要添加的属性名称,不可为 Null。</param>
|
|
/// <param name="value">将要添加的属性值。</param>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
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<JProperty>();
|
|
foreach (var child in children)
|
|
{
|
|
if (child.Name == name)
|
|
{
|
|
_jobject.Remove(name);
|
|
break;
|
|
}
|
|
}
|
|
|
|
_jobject.Add(name, value);
|
|
return true;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
|
|
/// <param name="name">将要添加的属性名称,不可为 Null。</param>
|
|
/// <param name="value">将要添加的属性值。</param>
|
|
/// <exception cref="System.ArgumentException"></exception>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
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<JProperty>();
|
|
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
|
|
|
|
/// <summary>获取所有类型为 Value 的子项。</summary>
|
|
public Json[] GetValues()
|
|
{
|
|
var ab = new ArrayBuilder<Json>();
|
|
if (_jarray != null)
|
|
{
|
|
var children = _jarray.Children<JValue>();
|
|
foreach (var child in children)
|
|
{
|
|
var json = new Json(child);
|
|
ab.Add(json);
|
|
}
|
|
}
|
|
return ab.Export();
|
|
}
|
|
|
|
/// <summary>获取所有类型为 Object 的子项。</summary>
|
|
public Json[] GetObjects()
|
|
{
|
|
var ab = new ArrayBuilder<Json>();
|
|
if (_jarray != null)
|
|
{
|
|
var children = _jarray.Children<JObject>();
|
|
foreach (var child in children)
|
|
{
|
|
var json = new Json(child);
|
|
ab.Add(json);
|
|
}
|
|
}
|
|
return ab.Export();
|
|
}
|
|
|
|
/// <summary>获取 Array 中的所有元素。</summary>
|
|
public Json[] GetItems()
|
|
{
|
|
var ab = new ArrayBuilder<Json>();
|
|
if (_jarray != null)
|
|
{
|
|
var children = _jarray.Children();
|
|
foreach (var child in children)
|
|
{
|
|
var json = new Json(child);
|
|
ab.Add(json);
|
|
}
|
|
}
|
|
return ab.Export();
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Array 时添加 Null 元素。</summary>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
public bool AddItem()
|
|
{
|
|
if (_jarray == null || TokenType != JTokenType.Array)
|
|
{
|
|
if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
|
|
return false;
|
|
}
|
|
|
|
_jarray.Add(JValue.CreateNull());
|
|
return true;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Array 时添加元素。</summary>
|
|
/// <param name="json">将要添加的元素。</param>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
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;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Array 时添加元素。</summary>
|
|
/// <param name="value">将要添加的元素。</param>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
public bool AddItem(string value)
|
|
{
|
|
if (_jarray == null || TokenType != JTokenType.Array)
|
|
{
|
|
if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
|
|
return false;
|
|
}
|
|
|
|
_jarray.Add(value ?? "");
|
|
return true;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Array 时添加元素。</summary>
|
|
/// <param name="value">将要添加的元素。</param>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
public bool AddItem(bool value)
|
|
{
|
|
if (_jarray == null || TokenType != JTokenType.Array)
|
|
{
|
|
if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
|
|
return false;
|
|
}
|
|
|
|
_jarray.Add(value);
|
|
return true;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Array 时添加元素。</summary>
|
|
/// <param name="value">将要添加的元素。</param>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
public bool AddItem(int value)
|
|
{
|
|
if (_jarray == null || TokenType != JTokenType.Array)
|
|
{
|
|
if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
|
|
return false;
|
|
}
|
|
|
|
_jarray.Add(value);
|
|
return true;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Array 时添加元素。</summary>
|
|
/// <param name="value">将要添加的元素。</param>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
public bool AddItem(long value)
|
|
{
|
|
if (_jarray == null || TokenType != JTokenType.Array)
|
|
{
|
|
if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
|
|
return false;
|
|
}
|
|
|
|
_jarray.Add(value);
|
|
return true;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Array 时添加元素。</summary>
|
|
/// <param name="value">将要添加的元素。</param>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
public bool AddItem(float value)
|
|
{
|
|
if (_jarray == null || TokenType != JTokenType.Array)
|
|
{
|
|
if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
|
|
return false;
|
|
}
|
|
|
|
_jarray.Add(value);
|
|
return true;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Array 时添加元素。</summary>
|
|
/// <param name="value">将要添加的元素。</param>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
public bool AddItem(double value)
|
|
{
|
|
if (_jarray == null || TokenType != JTokenType.Array)
|
|
{
|
|
if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
|
|
return false;
|
|
}
|
|
|
|
_jarray.Add(value);
|
|
return true;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Array 时添加元素。</summary>
|
|
/// <param name="value">将要添加的元素。</param>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
public bool AddItem(decimal value)
|
|
{
|
|
if (_jarray == null || TokenType != JTokenType.Array)
|
|
{
|
|
if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
|
|
return false;
|
|
}
|
|
|
|
_jarray.Add(value);
|
|
return true;
|
|
}
|
|
|
|
/// <summary>从 Parent 中移除。</summary>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
|
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
|
|
|
|
/// <summary>Json 对象实例为空。</summary>
|
|
public bool IsNone { get { return TokenType == JTokenType.None; } }
|
|
|
|
/// <summary>Json 对象为 Object 实例。</summary>
|
|
public bool IsObject { get { return TokenType == JTokenType.Object; } }
|
|
|
|
/// <summary>Json 对象为 Array 实例。</summary>
|
|
public bool IsArray { get { return TokenType == JTokenType.Array; } }
|
|
|
|
/// <summary>Json 对象为 Property 实例。</summary>
|
|
public bool IsProperty { get { return TokenType == JTokenType.Property; } }
|
|
|
|
/// <summary>Json 对象为 String 实例。</summary>
|
|
public bool IsString { get { return TokenType == JTokenType.String; } }
|
|
|
|
/// <summary>当前实例类型为 Property 时设置 Null 值。</summary>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
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;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Property 时设置值。</summary>
|
|
/// <param name="value">将要设置的值。</param>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
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;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Property 时设置值。</summary>
|
|
/// <param name="value">将要设置的值。</param>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
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;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Property 时设置值。</summary>
|
|
/// <param name="value">将要设置的值。</param>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
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;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Property 时设置值。</summary>
|
|
/// <param name="value">将要设置的值。</param>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
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;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Property 时设置值。</summary>
|
|
/// <param name="value">将要设置的值。</param>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
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;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Property 时设置值。</summary>
|
|
/// <param name="value">将要设置的值。</param>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
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;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Property 时设置值。</summary>
|
|
/// <param name="value">将要设置的值。</param>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
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;
|
|
}
|
|
|
|
/// <summary>当前实例类型为 Property 时设置值。</summary>
|
|
/// <param name="value">将要设置的值。</param>
|
|
/// <exception cref="System.InvalidOperationException"></exception>
|
|
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
|
|
|
|
/// <summary>解析文本为 Json 对象,失败时返回 Null。</summary>
|
|
/// <exception cref="System.Exception"></exception>
|
|
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
|
|
|
|
/// <summary>解析实现 IList 的对象为 Json 对象,失败时返回 Null。</summary>
|
|
/// <param name="entity">将要解析的对象。</param>
|
|
/// <param name="lower">在 Json 中将属性名称转换为小写。</param>
|
|
/// <param name="depth">限制 Json 层级深度,当值小于零时将不限制深度。</param>
|
|
/// <param name="force">强制解析属性,忽略 Serializable 特性。</param>
|
|
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);
|
|
}
|
|
|
|
/// <summary>解析实现 IDictionary 的对象为 Json 对象,失败时返回 Null。</summary>
|
|
/// <param name="entity">将要解析的对象。</param>
|
|
/// <param name="lower">在 Json 中将属性名称转换为小写。</param>
|
|
/// <param name="depth">限制 Json 层级深度,当值小于零时将不限制深度。</param>
|
|
/// <param name="force">强制解析属性,忽略 Serializable 特性。</param>
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>解析对象为 Json 对象,包含所有公共属性,失败时返回 Null。</para>
|
|
/// <para>String 对象将解析文本;Json 对象将返回实例;String 对象将解析文本;实现 IDictionary 或 IList 的对象将解析内容。</para>
|
|
/// </summary>
|
|
/// <param name="entity">将要解析的对象。</param>
|
|
/// <param name="lower">在 Json 中将属性名称转换为小写。</param>
|
|
/// <param name="depth">限制 Json 层级深度,当值小于零时将不限制深度。</param>
|
|
/// <param name="force">强制解析属性,忽略 Serializable 特性。</param>
|
|
/// <exception cref="System.Exception"></exception>
|
|
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();
|
|
// IList 不再需要 SerializableAttribute 特性。
|
|
// {
|
|
// var ltype = list.GetType();
|
|
// var sas = ltype.GetCustomAttributes(typeof(SerializableAttribute), false);
|
|
// if (sas == null || sas.Length < 1) return null;
|
|
// }
|
|
|
|
var checker = list as IToJsonChecker;
|
|
var json = NewArray();
|
|
try
|
|
{
|
|
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;
|
|
|
|
// 处理 Type 对象。
|
|
if (value.GetType().Equals(typeof(Type)) && (previous.Length > 2))
|
|
{
|
|
value = ((Type)value).FullName;
|
|
}
|
|
|
|
// 处理 Assembly 对象。
|
|
if (value.GetType().Equals(typeof(Assembly)) && (previous.Length > 2))
|
|
{
|
|
value = ((Assembly)value).FullName;
|
|
}
|
|
|
|
if (value == null) { json.AddItem(); }
|
|
else if (value is DateTime) { json.AddItem(value.ToString()); }
|
|
else if (value is Boolean) { json.AddItem((Boolean)value); }
|
|
else if (value is Int32) { json.AddItem((Int32)value); }
|
|
else if (value is Int64) { json.AddItem((Int64)value); }
|
|
else if (value is Single) { json.AddItem((Single)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<object>();
|
|
recursive.Add(previous);
|
|
recursive.Add(value);
|
|
|
|
if (value is IDictionary) { json.AddItem(From(value as IDictionary, lower, recursive, depth, force)); }
|
|
else if (value is IList) { json.AddItem(From(value as IList, lower, recursive, depth, force)); }
|
|
else { json.AddItem(From(value, lower, recursive, depth, force)); }
|
|
}
|
|
else
|
|
{
|
|
json.AddItem(value.ToString());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch { }
|
|
return json;
|
|
}
|
|
|
|
private static Json From(IDictionary dictionary, bool lower, object[] previous, int depth, bool force)
|
|
{
|
|
if (dictionary == null) return null;
|
|
if (dictionary is IToJson) return ((IToJson)dictionary).ToJson();
|
|
// IDictionary 不再需要 SerializableAttribute 特性。
|
|
// {
|
|
// var dtype = dictionary.GetType();
|
|
// var sas = dtype.GetCustomAttributes(typeof(SerializableAttribute), false);
|
|
// if (sas == null || sas.Length < 1) return null;
|
|
// }
|
|
|
|
var checker = dictionary as IToJsonChecker;
|
|
var json = NewObject();
|
|
try
|
|
{
|
|
var keys = dictionary.Keys;
|
|
foreach (var key in keys)
|
|
{
|
|
if (key == null) continue;
|
|
try
|
|
{
|
|
var field = key.ToString() ?? "";
|
|
if (lower && !string.IsNullOrEmpty(field)) field = field.ToLower();
|
|
|
|
var value = dictionary[key];
|
|
|
|
// 检查递归引用。
|
|
var recursively = false;
|
|
foreach (var r in previous)
|
|
{
|
|
if (ReferenceEquals(r, value))
|
|
{
|
|
if (AllowRecursively) json.SetProperty(field);
|
|
recursively = true;
|
|
break;
|
|
}
|
|
}
|
|
if (recursively) continue;
|
|
|
|
// 检查 System.Attribute.TypeId。
|
|
if (field == "TypeId" || field == "typeid")
|
|
{
|
|
if ((value != null) && (value is Type))
|
|
{
|
|
json.SetProperty(field, ((Type)value).FullName);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// 由 IToJsonChecker 实现的方法检查是否包含元素。
|
|
if (checker != null && !checker.WithPropertyInJson(dictionary, field, value)) continue;
|
|
|
|
if (value != null)
|
|
{
|
|
// 处理 Type 对象。
|
|
if (value.GetType().Equals(typeof(Type)) && (previous.Length > 2))
|
|
{
|
|
value = ((Type)value).FullName;
|
|
}
|
|
|
|
// 处理 Assembly 对象。
|
|
if (value.GetType().Equals(typeof(Assembly)) && (previous.Length > 2))
|
|
{
|
|
value = ((Assembly)value).FullName;
|
|
}
|
|
}
|
|
|
|
if (value == null) { json.AddItem(); }
|
|
else if (value is DateTime) { json.SetProperty(field, value.ToString()); }
|
|
else if (value is Boolean) { json.SetProperty(field, (Boolean)value); }
|
|
else if (value is Int32) { json.SetProperty(field, (Int32)value); }
|
|
else if (value is Int64) { json.SetProperty(field, (Int64)value); }
|
|
else if (value is Single) { json.SetProperty(field, (Single)value); }
|
|
else if (value is Double) { json.SetProperty(field, (Double)value); }
|
|
else if (value is Decimal) { json.SetProperty(field, (Decimal)value); }
|
|
else if (value is String) { json.SetProperty(field, (String)value); }
|
|
else if (value is Json) { json.SetProperty(field, value as Json); }
|
|
else
|
|
{
|
|
if ((depth < 0) || (0 < depth && previous.Length < depth))
|
|
{
|
|
var recursive = new ArrayBuilder<object>();
|
|
recursive.Add(previous);
|
|
recursive.Add(value);
|
|
|
|
if (value is IDictionary) { json.SetProperty(field, From(value as IDictionary, lower, recursive, depth, force)); }
|
|
else if (value is IList) { json.SetProperty(field, From(value as IList, lower, recursive, depth, force)); }
|
|
else { json.SetProperty(field, From(value, lower, recursive, depth, force)); }
|
|
}
|
|
else
|
|
{
|
|
json.SetProperty(field, value.ToString());
|
|
}
|
|
}
|
|
}
|
|
catch { }
|
|
}
|
|
}
|
|
catch { }
|
|
return json;
|
|
}
|
|
|
|
private static Json From(object entity, bool lower, object[] previous, int depth, bool force)
|
|
{
|
|
if (entity == null) return null;
|
|
if (entity is IToJson) return ((IToJson)entity).ToJson();
|
|
if (!force && !CanSerialize(entity.GetType(), false)) return null;
|
|
|
|
var type = null as Type;
|
|
try { type = entity.GetType(); }
|
|
catch (Exception exception)
|
|
{
|
|
if (AllowException) throw exception;
|
|
return null;
|
|
}
|
|
|
|
if (entity is Json) { if (lower) Lower(entity as Json); return entity as Json; }
|
|
else if (entity is String) { return From((String)entity); }
|
|
else if (entity is IDictionary) { return From(entity as IDictionary, (bool)lower); }
|
|
else if (entity is IList) { return From(entity as IList, (bool)lower); }
|
|
|
|
var independent = RuntimeUtility.Contains<IndependentAttribute>(type);
|
|
var checker = entity as IToJsonChecker;
|
|
var properties = type.GetProperties();
|
|
if (properties.LongLength > 0L)
|
|
{
|
|
var dict = new Dictionary<string, object>();
|
|
foreach (var property in properties)
|
|
{
|
|
var field = property.Name;
|
|
if (field == null) continue;
|
|
|
|
// 有 Independent 的对象不包含继承属性。
|
|
if (independent)
|
|
{
|
|
if (!property.DeclaringType.Equals(type)) continue;
|
|
}
|
|
|
|
// 处理 Assembly 对象的 DefinedTypes 和 ExportedTypes 属性。
|
|
if (entity is Assembly)
|
|
{
|
|
var assembly = entity as Assembly;
|
|
if (assembly != null)
|
|
{
|
|
if (field == "DefinedTypes" || field == "ExportedTypes")
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
var getter = property.GetGetMethod(false);
|
|
if (getter == null) continue;
|
|
if (getter.IsStatic) continue;
|
|
|
|
var value = null as object;
|
|
try
|
|
{
|
|
value = getter.Invoke((object)entity, null);
|
|
|
|
// 由 IToJsonChecker 实现的方法检查是否包含元素。
|
|
if (checker != null && !checker.WithPropertyInJson(entity, property, value)) continue;
|
|
|
|
// 处理 Type 对象。
|
|
if (getter.ReturnType.Equals(typeof(Type)) && (previous.Length > 2))
|
|
{
|
|
value = ((Type)value).FullName;
|
|
}
|
|
|
|
// 处理 Assembly 对象。
|
|
if (getter.ReturnType.Equals(typeof(Assembly)) && (previous.Length > 2))
|
|
{
|
|
value = ((Assembly)value).FullName;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
value = ex.Message;
|
|
}
|
|
|
|
if (!dict.ContainsKey(field)) dict.Add(field, value);
|
|
}
|
|
var json = From(dict, lower, previous, depth, force);
|
|
return json;
|
|
}
|
|
else
|
|
{
|
|
return NewObject();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Json -> String
|
|
|
|
/// <summary>导出文本,可指定缩进。若类型为 String,则导出 String 值,忽略缩进。</summary>
|
|
internal static string Export(Json json, bool indented)
|
|
{
|
|
if (json == null) return "";
|
|
if (json._jtoken == null) return "";
|
|
if (json.TokenType == JTokenType.String && json._jvalue != null)
|
|
{
|
|
return json._jvalue.Value.ToString();
|
|
}
|
|
|
|
return json._jtoken.ToString(indented ? Formatting.Indented : Formatting.None);
|
|
}
|
|
|
|
/// <summary>生成字符串,默认不缩进。若类型为 String,则导出 String 值。</summary>
|
|
public override string ToString() => Export(this, false);
|
|
|
|
/// <summary>生成字符串,可指定缩进。若类型为 String,则导出 String 值,忽略缩进。</summary>
|
|
public string ToString(bool indented) => Export(this, indented);
|
|
|
|
#endregion
|
|
|
|
#region Json -> Object
|
|
|
|
/// <summary>填充类型实例,失败时返回 NULL 值。</summary>
|
|
internal static T Object<T>(Json json, bool ignoreCase = true, string ignoreCharacters = null, bool force = false) where T : class, new()
|
|
{
|
|
if (json == null) return null;
|
|
if (json._jtoken == null) return null;
|
|
if (json.TokenType != JTokenType.Object) return null;
|
|
|
|
var entity = Activator.CreateInstance(typeof(T));
|
|
Object(entity, json, ignoreCase, ignoreCharacters, force);
|
|
return (T)entity;
|
|
}
|
|
|
|
/// <summary>将 Json 填充到数组列表,失败时返回 NULL 值。</summary>
|
|
internal static T[] Array<T>(Json json, bool ignoreCase = true, string ignoreCharacters = null, bool force = false) where T : class, new()
|
|
{
|
|
if (json == null) return null;
|
|
if (json._jtoken == null) return null;
|
|
if (json.TokenType != JTokenType.Array) return null;
|
|
|
|
var list = new List<T>();
|
|
Array(list, json, ignoreCase, ignoreCharacters, force);
|
|
return list.ToArray();
|
|
}
|
|
|
|
/// <summary></summary>
|
|
public static void Object(object entity, Json json, bool ignoreCase, string ignoreCharacters, bool force)
|
|
{
|
|
if (entity == null || json == null) return;
|
|
if (json.TokenType != JTokenType.Object) return;
|
|
|
|
var jps = json.GetProperties();
|
|
if (jps.Length < 1) return;
|
|
|
|
var etype = entity.GetType();
|
|
var eps = etype.GetProperties();
|
|
if (eps.Length < 1) return;
|
|
|
|
foreach (var ep in eps)
|
|
{
|
|
foreach (var jp in jps)
|
|
{
|
|
var jpn = TextUtility.Trim(jp.Name);
|
|
var epn = TextUtility.Trim(ep.Name);
|
|
|
|
if (ignoreCharacters != null)
|
|
{
|
|
var characters = ignoreCharacters.ToCharArray();
|
|
foreach (var character in characters)
|
|
{
|
|
jpn.Replace(character.ToString(), "");
|
|
epn.Replace(character.ToString(), "");
|
|
}
|
|
}
|
|
|
|
if (ignoreCase)
|
|
{
|
|
if (jpn.Length > 0) jpn = jpn.ToLower();
|
|
if (epn.Length > 0) epn = epn.ToLower();
|
|
}
|
|
|
|
if (jpn.Length < 1 || epn.Length < 1) continue;
|
|
if (jpn != epn) continue;
|
|
|
|
var value = jp.Value;
|
|
if (value == null) continue;
|
|
|
|
Property(entity, ep, value, ignoreCase, ignoreCharacters, force);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void Add(object entity, object item, int index)
|
|
{
|
|
try
|
|
{
|
|
if (entity is Array array)
|
|
{
|
|
array.SetValue(item, index);
|
|
}
|
|
else if (entity is IList list)
|
|
{
|
|
list.Add(entity);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (_throw) throw ex;
|
|
}
|
|
}
|
|
|
|
internal static void Array(object array, Json json, bool ignoreCase, string ignoreCharacters, bool force)
|
|
{
|
|
if (array == null) return;
|
|
if (json == null) return;
|
|
if (json.TokenType != JTokenType.Array) return;
|
|
|
|
var type = array.GetType();
|
|
var subtype = null as Type;
|
|
if (array is Array)
|
|
{
|
|
string typeName = array.GetType().FullName.Replace("[]", string.Empty);
|
|
subtype = array.GetType().Assembly.GetType(typeName);
|
|
}
|
|
else
|
|
{
|
|
var subtypes = type.GetGenericArguments();
|
|
if (subtypes.Length < 1) return;
|
|
subtype = subtypes[0];
|
|
}
|
|
|
|
var jis = json.GetItems();
|
|
for (var index = 0; index < jis.Length; index++)
|
|
{
|
|
var ji = jis[index];
|
|
if (subtype.Equals(typeof(Json))) Add(array, ji, index);
|
|
else if (subtype.Equals(typeof(string))) Add(array, (ji.TokenType == JTokenType.Null) ? null : ji.Text, index);
|
|
else if (subtype.Equals(typeof(byte))) Add(array, NumberUtility.Byte(ji.Text), index);
|
|
else if (subtype.Equals(typeof(short))) Add(array, NumberUtility.Int16(ji.Text), index);
|
|
else if (subtype.Equals(typeof(int))) Add(array, NumberUtility.Int32(ji.Text), index);
|
|
else if (subtype.Equals(typeof(long))) Add(array, NumberUtility.Int64(ji.Text), index);
|
|
else if (subtype.Equals(typeof(sbyte))) Add(array, NumberUtility.SByte(ji.Text), index);
|
|
else if (subtype.Equals(typeof(ushort))) Add(array, NumberUtility.UInt16(ji.Text), index);
|
|
else if (subtype.Equals(typeof(uint))) Add(array, NumberUtility.UInt32(ji.Text), index);
|
|
else if (subtype.Equals(typeof(ulong))) Add(array, NumberUtility.UInt64(ji.Text), index);
|
|
else if (subtype.Equals(typeof(float))) Add(array, NumberUtility.Single(ji.Text), index);
|
|
else if (subtype.Equals(typeof(double))) Add(array, NumberUtility.Double(ji.Text), index);
|
|
else if (subtype.Equals(typeof(decimal))) Add(array, NumberUtility.Decimal(ji.Text), index);
|
|
else
|
|
{
|
|
var serializable = force ? true : CanSerialize(subtype, false);
|
|
if (serializable && (ji is Json))
|
|
{
|
|
switch (ji.TokenType)
|
|
{
|
|
case JTokenType.Object:
|
|
var subobject = Activator.CreateInstance(subtype);
|
|
Object(subobject, ji, ignoreCase, ignoreCharacters, force);
|
|
Add(array, subobject, index);
|
|
break;
|
|
case JTokenType.Array:
|
|
var subarray = Activator.CreateInstance(subtype);
|
|
Array(subarray, ji, ignoreCase, ignoreCharacters, force);
|
|
Add(array, subarray, index);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void Property(object entity, PropertyInfo property, object value, bool ignoreCase, string ignoreCharacters, bool force)
|
|
{
|
|
if (entity == null) return;
|
|
if (property == null) return;
|
|
if (value == null) return;
|
|
|
|
var setter = property.GetSetMethod();
|
|
if (setter == null) return;
|
|
|
|
var pt = property.PropertyType;
|
|
var ptname = property.PropertyType.FullName;
|
|
var parameter = new object[1] { null };
|
|
|
|
if (ptname == typeof(Json).FullName)
|
|
{
|
|
if (value is Json)
|
|
{
|
|
parameter[0] = value;
|
|
setter.Invoke(entity, parameter);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (ptname)
|
|
{
|
|
case "System.DateTime":
|
|
try
|
|
{
|
|
parameter[0] = DateTime.Parse(value.ToString());
|
|
setter.Invoke(entity, parameter);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
if (AllowException) throw exception;
|
|
parameter[0] = TextUtility.Empty;
|
|
setter.Invoke(entity, parameter);
|
|
}
|
|
break;
|
|
case "System.String":
|
|
if (value is Json) parameter[0] = ((Json)value).TokenType == JTokenType.Null ? null : ((Json)value).Text;
|
|
else parameter[0] = value.ToString();
|
|
setter.Invoke(entity, parameter);
|
|
break;
|
|
case "System.Int32":
|
|
parameter[0] = NumberUtility.Int32(value.ToString());
|
|
setter.Invoke(entity, parameter);
|
|
break;
|
|
case "System.Int64":
|
|
parameter[0] = NumberUtility.Int64(value.ToString());
|
|
setter.Invoke(entity, parameter);
|
|
break;
|
|
case "System.Double":
|
|
parameter[0] = NumberUtility.Double(value.ToString());
|
|
setter.Invoke(entity, parameter);
|
|
break;
|
|
case "System.Decimal":
|
|
parameter[0] = NumberUtility.Decimal(value.ToString());
|
|
setter.Invoke(entity, parameter);
|
|
break;
|
|
default:
|
|
var serializable = force;
|
|
if (!serializable) serializable = CanSerialize(property.PropertyType, false);
|
|
if (serializable && (value is Json))
|
|
{
|
|
switch (((Json)value).TokenType)
|
|
{
|
|
case JTokenType.Object:
|
|
var subobject = Activator.CreateInstance(property.PropertyType);
|
|
Object(subobject, (Json)value, ignoreCase, ignoreCharacters, force);
|
|
parameter[0] = subobject;
|
|
setter.Invoke(entity, parameter);
|
|
break;
|
|
case JTokenType.Array:
|
|
object subarray;
|
|
if (pt.BaseType != null && pt.BaseType.Equals(typeof(Array)))
|
|
{
|
|
subarray = new object();
|
|
var length = ((Json)value).GetItems().Length;
|
|
subarray = pt.InvokeMember("Set", BindingFlags.CreateInstance, null, subarray, new object[] { length });
|
|
}
|
|
else
|
|
{
|
|
subarray = Activator.CreateInstance(property.PropertyType);
|
|
}
|
|
Array(subarray, (Json)value, ignoreCase, ignoreCharacters, force);
|
|
parameter[0] = subarray;
|
|
setter.Invoke(entity, parameter);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region Dynamic
|
|
|
|
#if !NET20
|
|
|
|
/// <summary></summary>
|
|
public override bool TryGetMember(GetMemberBinder binder, out object result)
|
|
{
|
|
var contains = false;
|
|
if (IsObject)
|
|
{
|
|
var property = GetProperty(binder.Name);
|
|
contains = property != null;
|
|
result = contains ? property.Value : null;
|
|
return contains;
|
|
}
|
|
|
|
result = null;
|
|
return contains;
|
|
}
|
|
|
|
/// <summary></summary>
|
|
public override bool TrySetMember(SetMemberBinder binder, object value)
|
|
{
|
|
var name = binder.Name;
|
|
|
|
if (value == null) return SetProperty(name);
|
|
if (value is Json) return SetProperty(name, (Json)value);
|
|
if (value is string) return SetProperty(name, (string)value);
|
|
if (value is bool) return SetProperty(name, (bool)value);
|
|
if (value is int) return SetProperty(name, (int)value);
|
|
if (value is long) return SetProperty(name, (long)value);
|
|
if (value is float) return SetProperty(name, (float)value);
|
|
if (value is double) return SetProperty(name, (double)value);
|
|
if (value is decimal) return SetProperty(name, (decimal)value);
|
|
|
|
return false;
|
|
}
|
|
|
|
#endif
|
|
|
|
#endregion
|
|
|
|
#region 运算符。
|
|
|
|
/// <summary>从 Json 到 Boolean 的隐式转换,判断 Json 对象可用。</summary>
|
|
public static implicit operator bool(Json json) => json != null && json.Available;
|
|
|
|
/// <summary>从 Json 到 String 的隐式转换,默认不缩进。</summary>
|
|
public static implicit operator string(Json json) => Export(json, false);
|
|
|
|
/// <summary>从 String 到 Json 的隐式转换。</summary>
|
|
/// <exception cref="System.Exception"></exception>
|
|
public static implicit operator Json(string text) => From(text);
|
|
|
|
#endregion
|
|
|
|
#region Statics
|
|
|
|
#region 创建实例。
|
|
|
|
/// <summary>创建新对象。</summary>
|
|
public static Json NewObject()
|
|
{
|
|
return new Json(new JObject());
|
|
}
|
|
|
|
/// <summary>创建新对象。</summary>
|
|
public static Json NewObject(Dictionary<string, string> dictionary)
|
|
{
|
|
var json = new Json(null);
|
|
json.Reset(dictionary);
|
|
return json;
|
|
}
|
|
|
|
/// <summary>创建新对象。</summary>
|
|
public static Json NewObject(TextSet dictionary)
|
|
{
|
|
var json = new Json(null);
|
|
json.Reset(dictionary);
|
|
return json;
|
|
}
|
|
|
|
/// <summary>创建新对象。</summary>
|
|
public static Json NewObject(ObjectSet<string> dictionary)
|
|
{
|
|
var json = new Json(null);
|
|
json.Reset(dictionary);
|
|
return json;
|
|
}
|
|
|
|
/// <summary>创建新对象。</summary>
|
|
public static Json NewArray()
|
|
{
|
|
return new Json(new JArray());
|
|
}
|
|
|
|
/// <summary>新建类型为 Property 的实例,值为 Null,失败时返回 Null。</summary>
|
|
/// <param name="name">Property 名称,不可为 Null。</param>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
public static Json NewProperty(string name)
|
|
{
|
|
if (name == null)
|
|
{
|
|
if (AllowException) throw new ArgumentNullException("name", "参数无效。");
|
|
return null;
|
|
}
|
|
return new Json(new JProperty(name, null));
|
|
}
|
|
|
|
/// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
|
|
/// <param name="name">Property 名称,不可为 Null。</param>
|
|
/// <param name="value">Property 值。</param>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
public static Json NewProperty(string name, string value)
|
|
{
|
|
if (name == null)
|
|
{
|
|
if (AllowException) throw new ArgumentNullException("name", "参数无效。");
|
|
return null;
|
|
}
|
|
return new Json(new JProperty(name, value));
|
|
}
|
|
|
|
/// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
|
|
/// <param name="name">Property 名称,不可为 Null。</param>
|
|
/// <param name="value">Property 值。</param>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
public static Json NewProperty(string name, bool value)
|
|
{
|
|
if (name == null)
|
|
{
|
|
if (AllowException) throw new ArgumentNullException("name", "参数无效。");
|
|
return null;
|
|
}
|
|
return new Json(new JProperty(name, value));
|
|
}
|
|
|
|
/// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
|
|
/// <param name="name">Property 名称,不可为 Null。</param>
|
|
/// <param name="value">Property 值。</param>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
public static Json NewProperty(string name, int value)
|
|
{
|
|
if (name == null)
|
|
{
|
|
if (AllowException) throw new ArgumentNullException("name", "参数无效。");
|
|
return null;
|
|
}
|
|
return new Json(new JProperty(name, value));
|
|
}
|
|
|
|
/// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
|
|
/// <param name="name">Property 名称,不可为 Null。</param>
|
|
/// <param name="value">Property 值。</param>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
public static Json NewProperty(string name, long value)
|
|
{
|
|
if (name == null)
|
|
{
|
|
if (AllowException) throw new ArgumentNullException("name", "参数无效。");
|
|
return null;
|
|
}
|
|
return new Json(new JProperty(name, value));
|
|
}
|
|
|
|
/// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
|
|
/// <param name="name">Property 名称,不可为 Null。</param>
|
|
/// <param name="value">Property 值。</param>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
public static Json NewProperty(string name, float value)
|
|
{
|
|
if (name == null)
|
|
{
|
|
if (AllowException) throw new ArgumentNullException("name", "参数无效。");
|
|
return null;
|
|
}
|
|
return new Json(new JProperty(name, value));
|
|
}
|
|
|
|
/// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
|
|
/// <param name="name">Property 名称,不可为 Null。</param>
|
|
/// <param name="value">Property 值。</param>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
public static Json NewProperty(string name, double value)
|
|
{
|
|
if (name == null)
|
|
{
|
|
if (AllowException) throw new ArgumentNullException("name", "参数无效。");
|
|
return null;
|
|
}
|
|
return new Json(new JProperty(name, value));
|
|
}
|
|
|
|
/// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
|
|
/// <param name="name">Property 名称,不可为 Null。</param>
|
|
/// <param name="value">Property 值。</param>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
public static Json NewProperty(string name, decimal value)
|
|
{
|
|
if (name == null)
|
|
{
|
|
if (AllowException) throw new ArgumentNullException("name", "参数无效。");
|
|
return null;
|
|
}
|
|
return new Json(new JProperty(name, value));
|
|
}
|
|
|
|
/// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
|
|
/// <param name="name">Property 名称,不可为 Null。</param>
|
|
/// <param name="value">Property 值。</param>
|
|
/// <exception cref="System.ArgumentNullException"></exception>
|
|
public static Json NewProperty(string name, Json value)
|
|
{
|
|
if (name == null)
|
|
{
|
|
if (AllowException) throw new ArgumentNullException("name", "参数无效。");
|
|
return null;
|
|
}
|
|
if (value == null) return new Json(new JProperty(name, null));
|
|
return new Json(new JProperty(name, null));
|
|
}
|
|
|
|
#endregion
|
|
|
|
/// <summary>格式化 Json 文本。</summary>
|
|
public static string Format(string text)
|
|
{
|
|
if (text == null || text == "") return "";
|
|
try
|
|
{
|
|
var serializer = new Newtonsoft.Json.JsonSerializer();
|
|
var tr = (System.IO.TextReader)(new System.IO.StringReader(text));
|
|
var jtr = new Newtonsoft.Json.JsonTextReader(tr);
|
|
var obj = serializer.Deserialize(jtr);
|
|
if (obj != null)
|
|
{
|
|
var textWriter = new System.IO.StringWriter();
|
|
var jsonWriter = new Newtonsoft.Json.JsonTextWriter(textWriter)
|
|
{
|
|
Formatting = Newtonsoft.Json.Formatting.Indented,
|
|
Indentation = 4,
|
|
IndentChar = ' '
|
|
};
|
|
serializer.Serialize(jsonWriter, obj);
|
|
return textWriter.ToString();
|
|
}
|
|
else
|
|
{
|
|
return text;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
return text ?? "";
|
|
}
|
|
}
|
|
|
|
/// <summary>重命名属性名称。</summary>
|
|
public static Json Rename(Json json, Func<string, string> renamer)
|
|
{
|
|
if (json == null) return null;
|
|
switch (json.TokenType)
|
|
{
|
|
case JTokenType.Array:
|
|
var items = json.GetItems();
|
|
foreach (var i in items) Rename(i, renamer);
|
|
break;
|
|
case JTokenType.Object:
|
|
var properties = json.GetProperties();
|
|
foreach (var i in properties)
|
|
{
|
|
Rename(i, renamer);
|
|
|
|
var name = i._jproperty.Name;
|
|
var value = i._jproperty.Value;
|
|
|
|
if (!string.IsNullOrEmpty(name))
|
|
{
|
|
var newName = renamer(name);
|
|
if (name != newName)
|
|
{
|
|
i.Remove();
|
|
json._jobject.Add(newName, value);
|
|
}
|
|
}
|
|
Rename(new Json(value), renamer);
|
|
}
|
|
break;
|
|
}
|
|
return json;
|
|
}
|
|
|
|
/// <summary>设置属性名称为小写。</summary>
|
|
public static Json Lower(Json json) => Rename(json, (old) => old.Lower());
|
|
|
|
/// <summary>设置属性名称为驼峰形式。</summary>
|
|
public static Json Camel(Json json) => Rename(json, (old) => TextUtility.Camel(old));
|
|
|
|
private static bool CanSerialize(Type type, bool inherit = false)
|
|
{
|
|
if (type == null) return false;
|
|
|
|
if (type.BaseType.Equals(typeof(Array))) return true;
|
|
|
|
var interfaces = type.GetInterfaces();
|
|
foreach (var i in interfaces)
|
|
{
|
|
if (i.Equals(typeof(IList))) return true;
|
|
}
|
|
|
|
if (type.Equals(typeof(object))) return false;
|
|
var sas = type.GetCustomAttributes(typeof(SerializableAttribute), inherit);
|
|
if (sas != null && sas.Length > 0) return true;
|
|
|
|
var tas = type.GetCustomAttributes(typeof(Source.TableAttribute), inherit);
|
|
if (tas != null && tas.Length > 0) return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>序列化指定对象为 JSON 字符串。</summary>
|
|
/// <param name="object">将要序列化的对象。</param>
|
|
/// <param name="onError">发生错误时的返回值。</param>
|
|
/// <param name="indented">使子对象缩进。</param>
|
|
public static string SerializeObject(object @object, bool indented = false, string onError = null)
|
|
{
|
|
try
|
|
{
|
|
return JsonConvert.SerializeObject(@object, indented ? Formatting.Indented : Formatting.None);
|
|
}
|
|
catch { return onError; }
|
|
}
|
|
|
|
/// <summary>反序列化 JSON 字符串为指定的类型。</summary>
|
|
/// <typeparam name="T">要反序列化的类型。</typeparam>
|
|
/// <param name="json">将要反序列化的 JSON 字符串。</param>
|
|
/// <param name="onError">发生错误时的返回值。</param>
|
|
public static T DeserializeObject<T>(string json, T onError = default(T))
|
|
{
|
|
try
|
|
{
|
|
return JsonConvert.DeserializeObject<T>(json);
|
|
}
|
|
catch { return onError; }
|
|
}
|
|
|
|
/// <summary>反序列化 JSON 字符串为指定的匿名类型。</summary>
|
|
/// <typeparam name="T">要反序列化的类型</typeparam>
|
|
/// <param name="json">将要反序列化的 JSON 字符串。</param>
|
|
/// <param name="anonymousObject">匿名对象。</param>
|
|
/// <param name="onError">发生错误时的返回值。</param>
|
|
/// <returns>匿名对象。</returns>
|
|
public static T DeserializeAnonymous<T>(string json, T anonymousObject, T onError = default(T))
|
|
{
|
|
try
|
|
{
|
|
return JsonConvert.DeserializeAnonymousType(json, anonymousObject);
|
|
}
|
|
catch { return onError; }
|
|
}
|
|
|
|
#if !NET20
|
|
|
|
/// <summary>反序列化 JSON 字符串为指定的类型列表。</summary>
|
|
/// <typeparam name="T">要反序列化的类型。</typeparam>
|
|
/// <param name="json">将要反序列化的 JSON 字符串。</param>
|
|
/// <param name="returnNullOnError">发生错误时返回 NULL 值,设置为 FALSE 时返回空 List<<typeparamref name="T"/>> 对象。</param>
|
|
/// <returns></returns>
|
|
public static T[] DeserializeArray<T>(string json, bool returnNullOnError = false) where T : class
|
|
{
|
|
try
|
|
{
|
|
var serializer = new JsonSerializer();
|
|
var @object = null as object;
|
|
using (var sr = new StringReader(json))
|
|
{
|
|
using (var jtr = new JsonTextReader(sr))
|
|
{
|
|
@object = serializer.Deserialize(jtr, typeof(T[]));
|
|
}
|
|
}
|
|
return (@object as T[]) ?? new T[0];
|
|
}
|
|
catch { return returnNullOnError ? null : new T[0]; }
|
|
}
|
|
|
|
#endif
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
}
|
|
|