首页 > 代码库 > C#深入解析Json格式内容
C#深入解析Json格式内容
继上一篇《浅谈C#手动解析Json格式内容》我又来分析加入了一些功能让 这个解析类更实用
本章节最会开放我最终制作成功的Anonymous.Json.dll这个解析库 需要的拿走~
功能继上一篇增加了许多上一篇只是讲述了 解析的步骤但是 至于一些扩展的功能却没有涉及
本文将继续讲解
1.如何将json转换为一个类或者结构 甚至属性
2.如何将一个类或者结构甚至属性转换为json
就这两点就已经很头疼了 诶 废话不多说进入正题
上一篇一直有个很神秘的JsonObject没有讲解 现在先来揭开JsonObject的神秘面纱
internal bool _isArray = false;/// <summary>/// 是否为json array类型/// </summary>public bool IsArray{ get { return _isArray; }}internal bool _isString = false;/// <summary>/// 是否为json string类型/// </summary>public bool IsString{ get { return _isString; }}internal bool _isBool = false;/// <summary>/// 是否为json bool类型/// </summary>public bool IsBool{ get { return _isBool; }}internal bool _isObject = false;/// <summary>/// 是否为json object类型/// </summary>public bool IsObject{ get { return _isObject; }}internal bool _isChar = false;/// <summary>/// 是否为json char类型/// </summary>public bool IsChar{ get { return _isChar; }}internal bool _isInt;/// <summary>/// 是否为json 整数型/// </summary>public bool IsInt{ get { return _isInt; }}internal bool _isLong;/// <summary>/// 是否为json 长整数型/// </summary>public bool IsLong{ get { return _isLong; }}internal bool _isDouble;/// <summary>/// 是否为json 浮点型/// </summary>public bool IsDouble{ get { return _isDouble; }}internal bool _isNull = false;/// <summary>/// 是否为json null/// </summary>public bool IsNull{ get { return _isNull; }}/// <summary>/// 将object转换为JsonObject/// </summary>/// <param name="obj"></param>public JsonObject(object obj){ ConvertToJsonObject(this, obj);}/// <summary>/// 定义一个任意类型的隐式转换/// </summary>/// <param name="obj"></param>/// <returns></returns>public static implicit operator JsonObject(string obj){ return ImplicitConvert(obj);}public static implicit operator JsonObject(int obj){ return ImplicitConvert(obj);}public static implicit operator JsonObject(double obj){ return ImplicitConvert(obj);}public static implicit operator JsonObject(float obj){ return ImplicitConvert(obj);}public static implicit operator JsonObject(long obj){ return ImplicitConvert(obj);}public static implicit operator JsonObject(decimal obj){ return ImplicitConvert(obj);}private static JsonObject ImplicitConvert(object convert){ JsonObject obj = new JsonObject(); obj.ValueConvertToJsonObject(convert.ToString(), false); return obj;}/// <summary>/// 转换形态/// </summary>/// <param name="parent"></param>/// <param name="sourceObj"></param>/// <returns>如果是基本类型返回false直接进行设置</returns>private bool ConvertToJsonObject(JsonObject parent, object sourceObj){ if (sourceObj == null) return false; Type t = sourceObj.GetType(); if (t.IsGenericType) { Type ctorType = t.GetGenericTypeDefinition(); if (ctorType == typeof(List<>)) { parent._isArray = true; parent._sourceObj = new List<JsonObject>(); int count = (int)t.GetProperty("Count").GetValue(sourceObj, null); MethodInfo get = t.GetMethod("get_Item"); for (int i = 0; i < count; i++) { object value = http://www.mamicode.com/get.Invoke(sourceObj, new object[] { i }); JsonObject innerObj = new JsonObject(); if (!ConvertToJsonObject(innerObj, value)) { innerObj.ValueConvertToJsonObject(value.ToString(), false); } parent.add(innerObj); } } else if (ctorType == typeof(Dictionary<,>)) { parent._isObject = true; parent._sourceObj = new Dictionary<string, JsonObject>(); int count = (int)t.GetProperty("Count").GetValue(sourceObj, null); object kv_entity = t.GetMethod("GetEnumerator").Invoke(sourceObj, null); Type entityType = kv_entity.GetType(); for (int i = 0; i < count; i++) { bool mNext = (bool)entityType.GetMethod("MoveNext").Invoke(kv_entity, null); if (mNext) { object current = entityType.GetProperty("Current").GetValue(kv_entity, null); Type currentType = current.GetType(); object key = currentType.GetProperty("Key").GetValue(current, null); object value = http://www.mamicode.com/currentType.GetProperty("Value").GetValue(current, null); if (!(key is string)) throw new Exception("json规范格式不正确 Dictionary起始key应为string类型"); JsonObject innerObj = new JsonObject(); innerObj._key = key.ToString(); if (!ConvertToJsonObject(innerObj, value)) { innerObj.ValueConvertToJsonObject(value.ToString(), false); } parent.add(innerObj); } } } else { throw new Exception("不支持的泛型操作"); } return true; } else if (t.IsArray) { parent._isArray = true; parent._sourceObj = new List<JsonObject>(); int rank = t.GetArrayRank(); if (rank > 1) { throw new Exception("暂不支持超过1维的数组"); } else { int length_info = Convert.ToInt32(t.GetProperty("Length").GetValue(sourceObj, null)); for (int i = 0; i < length_info; i++) { object innerObj = t.GetMethod("GetValue", new Type[] { typeof(int) }).Invoke(sourceObj, new object[] { i }); JsonObject obj = new JsonObject(); if (!ConvertToJsonObject(obj, innerObj)) { obj.ValueConvertToJsonObject(innerObj.ToString(), false); } parent.add(obj); } } return true; } else if ((t.IsValueType && !t.IsPrimitive) || (t.IsClass && !(sourceObj is string))) { parent._isObject = true; parent._sourceObj = new Dictionary<string, JsonObject>(); PropertyInfo[] infos = t.GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (PropertyInfo item in infos) { JsonObject innerObj = new JsonObject(); innerObj._key = item.Name; object obj = item.GetValue(sourceObj, null); if (!ConvertToJsonObject(innerObj, obj)) { innerObj.ValueConvertToJsonObject(obj == null ? "null" : obj.ToString(), false); } parent.add(innerObj); } return true; } else { parent.ValueConvertToJsonObject(sourceObj.ToString(), false); return false; }}public JsonObject() { }/// <summary>/// 如果为json object提取索引内容/// </summary>/// <param name="index">key</param>/// <returns></returns>public JsonObject this[string index]{ get { if (IsObject) { if (ContainsKey(index)) { return dictionary()[index]; } else { throw new Exception("不包含 key: " + index); } } else { throw new Exception("该对象不是一个json object类型请用IsObject进行验证后操作"); } } set { if (IsObject) { if (value is JsonObject) { dictionary()[index] = value; } else { dictionary()[index] = new JsonObject(value); } } else { throw new Exception("该对象不是一个json object类型请用IsObject进行验证后操作"); } }}/// <summary>/// 如果为json array提取索引内容/// </summary>/// <param name="index">index</param>/// <returns></returns>public JsonObject this[int index]{ get { if (IsArray) { if (index >= Count || index <= -1) throw new Exception("索引超出数组界限"); return array()[index]; } else { throw new Exception("该对象不是一个json array类型请用IsArray进行验证后操作"); } } set { if (IsArray) { if (value is JsonObject) { array()[index] = value; } else { array()[index] = new JsonObject(value); } } else { throw new Exception("该对象不是一个json array类型请用IsArray进行验证后操作"); } }}/// <summary>/// 为json object 设置值如果存在则覆盖/// </summary>/// <param name="key"></param>/// <param name="value"></param>public void Set(string key, object value){ if (IsObject) { Dictionary<string, JsonObject> objs = dictionary(); if (objs.ContainsKey(key)) { if (value is JsonObject) objs[key] = (JsonObject)value; else objs[key] = new JsonObject(value); } else { if (value is JsonObject) objs.Add(key, (JsonObject)value); else objs.Add(key, new JsonObject(value)); } } else { this._isArray = false; this._isBool = false; this._isChar = false; this._isDouble = false; this._isInt = false; this._isLong = false; this._isNull = false; this._isObject = true; this._isString = false; this._key = null; this._sourceObj = new Dictionary<string, JsonObject>(); }}/// <summary>/// 为json object 设置值如果存在则覆盖/// </summary>/// <param name="key"></param>/// <param name="value"></param>public void Set<T>(string key, T value){ Set(key, value);}/// <summary>/// 为json array 添加值/// </summary>/// <param name="key"></param>/// <param name="value"></param>public void Add(object value){ if (IsArray) { List<JsonObject> objs = array(); if (value is JsonObject) objs.Add((JsonObject)value); else objs.Add(new JsonObject(value)); } else { this._isArray = true; this._isBool = false; this._isChar = false; this._isDouble = false; this._isInt = false; this._isLong = false; this._isNull = false; this._isObject = false; this._isString = false; this._key = null; this._sourceObj = new List<JsonObject>(); }}/// <summary>/// 为json array 添加值/// </summary>/// <param name="key"></param>/// <param name="value"></param>public void Add<T>(T value){ Add(value);}/// <summary>/// 删除一个json object针对json object/// </summary>/// <param name="key"></param>public void Remove(string key){ if (this.IsObject) { dictionary().Remove(key); }}/// <summary>/// 删除一个json object针对json array/// </summary>/// <param name="key"></param>public void Remove(int index){ if (this.IsArray) { array().RemoveAt(index); }}/// <summary>/// 检测json object是否包含这个key/// </summary>/// <param name="key"></param>/// <returns></returns>public bool ContainsKey(string key){ return dictionary().ContainsKey(key);}/// <summary>/// 获得json object或者json array的总数量/// </summary>public int Count{ get { if (IsArray) return array().Count; else if (IsObject) return dictionary().Count; return -1; }}/// <summary>/// 将json object原始数据转换出去/// </summary>/// <returns></returns>public override string ToString(){ return _sourceObj.ToString();}/// <summary>/// json key/// </summary>internal string _key;/// <summary>/// 源可替代为任何数据/// Dictionary<,>/// List<>/// String/// Int/// Double/// Bool/// 等/// </summary>internal object _sourceObj;/// <summary>/// 将源数据转换为json array/// </summary>/// <returns></returns>internal List<JsonObject> array(){ if (_sourceObj is List<JsonObject>) { return (List<JsonObject>)_sourceObj; } else { return null; }}/// <summary>/// 将源数据转换为json dictionary/// </summary>/// <returns></returns>internal Dictionary<string, JsonObject> dictionary(){ if (_sourceObj is Dictionary<string, JsonObject>) { return (Dictionary<string, JsonObject>)_sourceObj; } else { return null; }}/// <summary>/// 封装了个简便的添加方法/// </summary>/// <param name="obj"></param>internal void add(JsonObject obj){ if (this.IsObject) { Dictionary<string, JsonObject> objs = dictionary(); objs.Add(obj._key, obj); } else if (this.IsArray) { List<JsonObject> objs = array(); objs.Add(obj); }}/// <summary>/// 将json string 转换为对应的实体object/// </summary>/// <param name="value"></param>/// <param name="isFromComma">判断是否来自逗号这样好验证格式不正常的string</param>internal void ValueConvertToJsonObject(string value, bool isFromComma){ //如果为string类型解析开始解析 json string if (value is string) { string str = value.ToString(); bool isBaseType = false; if (str.IndexOf(".") != -1) { //尝试解析double double out_d = -1; if (double.TryParse(str, out out_d)) { isBaseType = true; this._isDouble = true; this._sourceObj = out_d; } } else { //尝试解析长整数型 long out_l = -1; if (long.TryParse(str, out out_l)) { isBaseType = true; //如果小于长整数 换算为整数类型 if (out_l <= int.MaxValue && out_l >= int.MinValue) { this._isInt = true; _sourceObj = (int)out_l; } else { this._isLong = true; _sourceObj = out_l; } } } if (!isBaseType) { if (str.ToLower().Equals("null")) { this._isNull = true; } else if (str.ToLower().Equals("true") || str.ToLower().Equals("false")) { this._isBool = true; this._sourceObj = bool.Parse(str.ToLower()); } else { if (!isFromComma) { this._isString = true; int idx = str.IndexOf("\\u"); while (idx != -1) { string v = str.Substring(idx, 6); string hex1 = v.Substring(2, 2); string hex2 = v.Substring(4); byte[] bytes = new byte[2] { Convert.ToByte(hex2,16), Convert.ToByte(hex1,16) }; str = str.Replace(v, Encoding.Unicode.GetString(bytes)); idx = str.IndexOf("\\u"); } _sourceObj = str; } else { throw new Exception("json字符串格式有误 请加单引号或双引号"); } } } }}/// <summary>/// 直接返回源数据/// </summary>/// <returns></returns>public object ToObject(){ return _sourceObj;}/// <summary>/// 转换为json串/// </summary>/// <returns></returns>public string ToJson(){ StringBuilder sb = new StringBuilder(); if (IsObject) { sb.Append("{"); Dictionary<string, JsonObject> objs = dictionary(); List<string> keys = new List<string>(objs.Keys); int i; for (i = 0; i < keys.Count - 1; i++) { sb.Append("\""); sb.Append(keys[i]); sb.Append("\":"); sb.Append(objs[keys[i]].ToJson()); sb.Append(","); } sb.Append("\""); sb.Append(keys[i]); sb.Append("\":"); sb.Append(objs[keys[i]].ToJson()); sb.Append("}"); } else if (IsArray) { sb.Append("["); List<JsonObject> objs = array(); int i; for (i = 0; i < objs.Count - 1; i++) { sb.Append(objs[i].ToJson()); sb.Append(","); } sb.Append(objs[i].ToJson()); sb.Append("]"); } else { if (!IsString) { if (IsBool) { sb.Append(((bool)_sourceObj) ? "true" : "false"); } else if (IsNull) { sb.Append("null"); } else { sb.Append(_sourceObj); } } else { sb.Append("\""); sb.Append(_sourceObj); sb.Append("\""); } } return sb.ToString();}/// <summary>/// 将jsonobject转换为实体object/// 有参的/// </summary>/// <typeparam name="T">实体object类型</typeparam>/// <param name="ctor">构造参数</param>/// <returns></returns>public T ToObject<T>(params object[] ctor){ object targetObj = null; if (this.IsObject || this.IsArray) { Type targetObjType = typeof(T); targetObj = CreateObject(targetObjType, ctor); } return (T)ConvertToObject(targetObj, this);}/// <summary>/// 将jsonobject转换为实体object/// 无参的/// </summary>/// <typeparam name="T">实体构造类型</typeparam>/// <returns></returns>public T ToObject<T>(){ return ToObject<T>(null);}private object ConvertToObject(object targetObj, JsonObject obj){ Type targetType = null; if (targetObj != null) targetType = targetObj.GetType(); //判断下object if (obj.IsObject) { Dictionary<string, JsonObject> dictionarys = obj.dictionary(); Dictionary<string, JsonObject>.Enumerator enumerator = dictionarys.GetEnumerator(); while (enumerator.MoveNext()) { string key = enumerator.Current.Key; JsonObject value = enumerator.Current.Value; PropertyInfo info = targetType.GetProperty(key, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public); if (targetType.IsGenericType) { if (targetType.GetGenericTypeDefinition() == typeof(Dictionary<,>)) { object setInnerValue = http://www.mamicode.com/null; Type innerValueType = targetType.GetGenericArguments()[1]; setInnerValue = GetJsonObjectEntity(innerValueType, value); setInnerValue = ConvertToObject(setInnerValue, value); MethodInfo add_info = targetType.GetMethod("Add"); add_info.Invoke(targetObj, new object[] { key, setInnerValue }); } else { throw new Exception("\"" + targetType.Name + "\"属性 \"" + key + "\"不是Dictionary泛型类型"); } } else if (info != null) { object innerObj = info.GetValue(targetObj, null); if (innerObj == null) innerObj = GetJsonObjectEntity(info.PropertyType, value); innerObj = ConvertToObject(innerObj, value); info.SetValue(targetObj, innerObj, null); } else { throw new Exception("\"" + targetType.Name + "\"类中找不到属性 \"" + key + "\"无法完成转换操作"); } } } else if (obj.IsArray) { List<JsonObject> arrays = obj.array(); for (int i = 0; i < arrays.Count; i++) { JsonObject item = arrays[i]; if (targetType.IsGenericType) { Type[] types = targetType.GetGenericArguments(); Type objType = types[0]; object innerObj = GetJsonObjectEntity(objType, item); innerObj = ConvertToObject(innerObj, item); MethodInfo info = targetType.GetMethod("Add"); info.Invoke(targetObj, new object[] { innerObj }); } else if (targetType.IsArray) { object innerObj = GetJsonObjectEntity(targetType, item); innerObj = ConvertToObject(innerObj, item); MethodInfo info = targetType.GetMethod("SetValue", new Type[] { typeof(object), typeof(int) }); info.Invoke(targetObj, new object[] { innerObj, i }); } } } else { return obj._sourceObj; } return targetObj;}private object GetJsonObjectEntity(Type type, JsonObject value){ object innerObj = null; if (value.IsObject && innerObj == null) { innerObj = CreateObject(type, null); } else if (value.IsArray) { if (innerObj == null) { if (type.IsGenericType) { innerObj = CreateObject(type, null); } else if (type.IsArray) { if (type.GetArrayRank() > 1) { throw new Exception("暂不支持1维数组以上的数据类型"); } innerObj = type.InvokeMember("Set", BindingFlags.CreateInstance, null, null, new object[] { value.Count }); } } } return innerObj;}private object CreateObject(Type objType, params object[] ctor){ try { object targetObj; if (ctor == null) targetObj = Activator.CreateInstance(objType); else targetObj = Activator.CreateInstance(objType, ctor); return targetObj; } catch (Exception ex) { throw new Exception("构造\"" + objType.FullName + "\"过程中出现异常 可能是类构造函数异常也可能是其他的异常 详细参见InnerException", ex); }}
恩 没错 这就是 这整个的JsonObject了 我基本加了隐式 转换 get set访问器删除方法 增加方法 设置方法等等 还真是功能繁多啊
其中支持 Array数组的转换 List<T>泛型的转换 甚至 Dictionary<string,TV>的转换 当然 字典类型的话key必须固定为string在复杂的json也不支持啊 嘿嘿
从上面的一堆Is***的属性来看是为了判断这个json object的类型 因为我定义了万能类 也就是说这个类既代表object也代表array
有个特殊的构造函数 是 public JsonObject(object obj) 这是为了自己手动构造json 所创建的
这个类也没什么好讲解的核心的就是 相互转换 还有ToJson这个方法 将这个类转换为Json格式内容
忘贴使用方法了....
这是为了 转换过来 当然可以忽略
public class obj{ public string obj1 { get; set; } public obj2 obj2 { get; set; } public List<object[]> array { get; set; } public object null_test { get; set; }}public class obj2{ public string a1 { get; set; }}
恩这才是货真价实的转换出来的代码~
string json = @"{ ‘obj1‘: ‘asd‘, ‘obj2‘: { ‘a1‘: ‘a1_test‘ }, ‘array‘: [ [ 1, 2, 3, 4, 5, true, null ] ], ‘null_test‘: null }";JsonSerialization js = new JsonSerialization(json);JsonObject jsonObj = js.Deserializa();obj o = js.Deserializa<obj>();//自定义构造jsonJsonObject obj2 = new JsonObject();obj2.Set("hello", "word");obj2.Set("obj", o);string str = obj2.ToJson();//str = {"hello":"word","obj":{"obj1":"asd","obj2":{"a1":"a1_test"},"array":[[1,2,3,4,5,true]],"null_test":null}}str = js.Serializa(obj2);//str = {"hello":"word","obj":{"obj1":"asd","obj2":{"a1":"a1_test"},"array":[[1,2,3,4,5,true]],"null_test":null}}string value = http://www.mamicode.com/obj2["hello"].ToObject<string>();//value = http://www.mamicode.com/word;
当然我做的这个也不是很完美 如果有啥问题 可以及时和我沟通 一起来完善~
QQ:1026926092 (ps:请注明来源否则不加)
完整类库在这里: 下载地址
原帖地址: http://www.cnblogs.com/anonymous5L/p/json_decode_deep.html
C#深入解析Json格式内容