首页 > 代码库 > 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);    }}
View Code

恩 没错 这就是 这整个的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格式内容