C#深入解析Json格式内容
繼上一篇《淺談C#手動解析Json格式內(nèi)容》我又來分析加入了一些功能讓 這個解析類更實用
本章節(jié)最會開放我最終制作成功的Anonymous.Json.dll這個解析庫 需要的拿走~
功能繼上一篇增加了許多上一篇只是講述了 ?解析的步驟但是 至于一些擴展的功能卻沒有涉及
本文將繼續(xù)講解
1.如何將json轉(zhuǎn)換為一個類或者結(jié)構(gòu) 甚至屬性
2.如何將一個類或者結(jié)構(gòu)甚至屬性轉(zhuǎn)換為json
就這兩點就已經(jīng)很頭疼了 誒 廢話不多說進入正題
?
上一篇一直有個很神秘的JsonObject沒有講解 現(xiàn)在先來揭開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 整數(shù)型 /// </summary> public bool IsInt {get { return _isInt; } }internal bool _isLong;/// <summary> /// 是否為json 長整數(shù)型 /// </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轉(zhuǎn)換為JsonObject /// </summary> /// <param name="obj"></param> public JsonObject(object obj) {ConvertToJsonObject(this, obj); }/// <summary> /// 定義一個任意類型的隱式轉(zhuǎn)換 /// </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> /// 轉(zhuǎn)換形態(tài) /// </summary> /// <param name="parent"></param> /// <param name="sourceObj"></param> /// <returns>如果是基本類型返回false直接進行設(shè)置</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 = 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 = currentType.GetProperty("Value").GetValue(current, null);if (!(key is string))throw new Exception("json規(guī)范格式不正確 Dictionary起始key應(yīng)為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維的數(shù)組");}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提取索引內(nèi)容 /// </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提取索引內(nèi)容 /// </summary> /// <param name="index">index</param> /// <returns></returns> public JsonObject this[int index] {get{if (IsArray){if (index >= Count || index <= -1)throw new Exception("索引超出數(shù)組界限");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 設(shè)置值如果存在則覆蓋 /// </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;elseobjs[key] = new JsonObject(value);}else{if (value is JsonObject)objs.Add(key, (JsonObject)value);elseobjs.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 設(shè)置值如果存在則覆蓋 /// </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);elseobjs.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的總數(shù)量 /// </summary> public int Count {get{if (IsArray)return array().Count;else if (IsObject)return dictionary().Count;return -1;} }/// <summary> /// 將json object原始數(shù)據(jù)轉(zhuǎn)換出去 /// </summary> /// <returns></returns> public override string ToString() {return _sourceObj.ToString(); }/// <summary> /// json key /// </summary> internal string _key; /// <summary> /// 源可替代為任何數(shù)據(jù) /// Dictionary<,> /// List<> /// String /// Int /// Double /// Bool /// 等 /// </summary> internal object _sourceObj;/// <summary> /// 將源數(shù)據(jù)轉(zhuǎn)換為json array /// </summary> /// <returns></returns> internal List<JsonObject> array() {if (_sourceObj is List<JsonObject>){return (List<JsonObject>)_sourceObj;}else{return null;} }/// <summary> /// 將源數(shù)據(jù)轉(zhuǎn)換為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 轉(zhuǎn)換為對應(yīng)的實體object /// </summary> /// <param name="value"></param> /// <param name="isFromComma">判斷是否來自逗號這樣好驗證格式不正常的string</param> internal void ValueConvertToJsonObject(string value, bool isFromComma) {//如果為string類型解析開始解析 json stringif (value is string){string str = value.ToString();bool isBaseType = false;if (str.IndexOf(".") != -1){//嘗試解析doubledouble out_d = -1;if (double.TryParse(str, out out_d)){isBaseType = true;this._isDouble = true;this._sourceObj = out_d;}}else{//嘗試解析長整數(shù)型long out_l = -1;if (long.TryParse(str, out out_l)){isBaseType = true;//如果小于長整數(shù) 換算為整數(shù)類型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> /// 直接返回源數(shù)據(jù) /// </summary> /// <returns></returns> public object ToObject() {return _sourceObj; }/// <summary> /// 轉(zhuǎn)換為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轉(zhuǎn)換為實體object /// 有參的 /// </summary> /// <typeparam name="T">實體object類型</typeparam> /// <param name="ctor">構(gòu)造參數(shù)</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轉(zhuǎn)換為實體object /// 無參的 /// </summary> /// <typeparam name="T">實體構(gòu)造類型</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();//判斷下objectif (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 = 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 + "\"無法完成轉(zhuǎn)換操作");}}}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維數(shù)組以上的數(shù)據(jù)類型");}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);elsetargetObj = Activator.CreateInstance(objType, ctor);return targetObj;}catch (Exception ex){throw new Exception("構(gòu)造\"" + objType.FullName + "\"過程中出現(xiàn)異常 可能是類構(gòu)造函數(shù)異常也可能是其他的異常 詳細參見InnerException", ex);} } View Code恩 沒錯 這就是 這整個的JsonObject了 我基本加了隱式 轉(zhuǎn)換 get set訪問器刪除方法 增加方法 設(shè)置方法等等 還真是功能繁多啊
其中支持 Array數(shù)組的轉(zhuǎn)換 ?List<T>泛型的轉(zhuǎn)換 甚至 Dictionary<string,TV>的轉(zhuǎn)換 ?當然 字典類型的話key必須固定為string在復(fù)雜的json也不支持啊 嘿嘿
從上面的一堆Is***的屬性來看是為了判斷這個json object的類型 ?因為我定義了萬能類 也就是說這個類既代表object也代表array
有個特殊的構(gòu)造函數(shù) 是?public JsonObject(object obj) 這是為了自己手動構(gòu)造json 所創(chuàng)建的
這個類也沒什么好講解的核心的就是 相互轉(zhuǎn)換 還有ToJson這個方法 將這個類轉(zhuǎn)換為Json格式內(nèi)容
?
忘貼使用方法了....
?這是為了 轉(zhuǎn)換過來 當然可以忽略
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; } }恩這才是貨真價實的轉(zhuǎn)換出來的代碼~
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>();//自定義構(gòu)造json JsonObject 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 = obj2["hello"].ToObject<string>(); //value = word;?
當然我做的這個也不是很完美 ?如果有啥問題 可以及時和我溝通 一起來完善~
經(jīng)過一位博友的點撥 做了IList的適配以及IDictionary的適配 還有一些特定的轉(zhuǎn)義字符的轉(zhuǎn)換~
QQ:1026926092 (ps:請注明來源否則不加)
完整類庫在這里:?下載地址
原帖地址:?http://www.cnblogs.com/anonymous5L/p/json_decode_deep.html
轉(zhuǎn)載于:https://www.cnblogs.com/anonymous5L/p/json_decode_deep.html
總結(jié)
以上是生活随笔為你收集整理的C#深入解析Json格式内容的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android】进入Material
- 下一篇: wow64