C#对象与Json互转
使用基础类
using System; using System.Collections.Generic; namespace JSON { /// <summary> /// 拓展Linq /// </summary> public static class TLinq { /// <summary> /// 跳过指定的数量的序列中的元素,然后返回剩余元素 /// </summary> /// <typeparam name="T">数据类型</typeparam> /// <param name="arr">原数组</param> /// <param name="skipCount">跳过的长度</param> /// <returns></returns> public static T[] Skip<T>(this T[] arr, int skipCount) { if (arr.Length > skipCount) { T[] res = new T[arr.Length - skipCount]; int num = 0; for (int i = skipCount; i < arr.Length; i++) { res[num] = arr[i]; num++; } return res; } else { throw new ArgumentException("skipCount大于arr长度"); } } /// <summary> /// 返回此数组的指定长度 /// </summary> /// <typeparam name="T">数据类型</typeparam> /// <param name="arr">原数组</param> /// <param name="length">指定长度</param> /// <returns></returns> public static T[] Take<T>(this T[] arr, int length) { if (length < arr.Length) { T[] res = new T[length]; for (int i = 0; i < length; i++) { res[i] = arr[i]; } return res; } else { throw new ArgumentException("length大于arr长度"); } } /// <summary> /// 反转元素 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="arr"></param> /// <returns></returns> public static T[] Reverse<T>(this T[] arr) { List<T> list = new List<T>(); for (int i = arr.Length - 1; i >= 0; i--) { list.Add(arr[i]); } return list.ToArray(); } /// <summary> /// 分割一次,从尾开始,返回剩余 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="arr"></param> /// <param name="last"></param> /// <param name="split"></param> /// <returns>返回剩余</returns> public static T[] SplitLast<T>(this T[] arr, out T[] last, params T[] split) { List<T> list = new List<T>(); int count = 0; if (null != split && split.Length > 0) { for (int i = arr.Length - 1; i >= 0; i--) { if (arr[i].Equals(split[split.Length - 1 - count])) { count++; if (count == split.Length) { last = Reverse(list.ToArray()); return arr.Take(arr.Length - (arr.Length - i)); } } else { if (i < arr.Length - 1 && count > 0) { list.Add(arr[i + 1]); } list.Add(arr[i]); count = 0; } } } last = default; return default; } /// <summary> /// 分割一次,从首开始,返回剩余 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="arr"></param> /// <param name="first"></param> /// <param name="split"></param> /// <returns>返回剩余</returns> public static T[] SplitFirst<T>(this T[] arr, out T[] first, params T[] split) { first = default; List<T> list = new List<T>(); int count = 0; if (null != split && split.Length > 0) { for (int i = 0; i < arr.Length; i++) { if (arr[i].Equals(split[count])) { count++; if (count == split.Length) { first = list.ToArray(); return i < arr.Length - 1 ? arr.Skip(i + 1) : default; } } else { if (i > 0 && count > 0) { list.Add(arr[i - 1]); } list.Add(arr[i]); count = 0; } } } return default; } /// <summary> /// 查看数组是否包含此字段 /// </summary> /// <typeparam name="T">数组类型</typeparam> /// <param name="arr">数组实例</param> /// <param name="any">比较方法</param> /// <returns></returns> public static bool Any<T>(this T[] arr, TLinq<T, bool> any) { foreach (var obj in arr) if (any(obj)) return true; return false; } /// <summary> /// 获取相同数 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="arr"></param> /// <param name="same"></param> /// <returns></returns> public static int Same<T>(this T[] arr, TLinq<T, bool> same) { int resNum = 0; foreach (var obj in arr) if (same(obj)) resNum++; return resNum; } /// <summary> /// 头相同个数 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="arr"></param> /// <param name="same"></param> /// <returns></returns> public static int SameHead<T>(this T[] arr, TLinq<T, bool> same) { int resNum = 0; foreach (var obj in arr) { if (same(obj)) { resNum++; continue; } else { break; } } return resNum; } /// <summary> /// 尾相同个数 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="arr"></param> /// <param name="same"></param> /// <returns></returns> public static int SameTail<T>(this T[] arr, TLinq<T, bool> same) { int resNum = 0; for (int i = arr.Length - 1; i >= 0; i--) { if (same(arr[i])) { resNum++; continue; } else { break; } } return resNum; } } /// <summary> /// 拓展Linq /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="T1"></typeparam> /// <param name="obj">参数对象</param> /// <returns></returns> public delegate T1 TLinq<in T, out T1>(T obj); }
对象转Json
using System; using System.Collections; using System.Reflection; using System.Text; namespace JSON { /// <summary> /// 模型转为JSON /// </summary> public static class ToJsonEx { /// <summary> /// 对象转换为Json /// </summary> /// <param name="obj"></param> /// <param name="ignores">忽略输出的属性(不区分大小写)</param> /// <returns></returns> public static string ToJson(this Object obj, params string[] ignores) { return ToJson(obj, false, ignores); } /// <summary> /// 转换为全部属性值是字符串的Json /// </summary> /// <param name="obj"></param> /// <param name="ignores">忽略输出的属性(不区分大小写)</param> /// <returns></returns> public static string ToAllStringJson(this Object obj, params string[] ignores) { return ToJson(obj, true, ignores); } /// <summary> /// 对象转换为Json /// </summary> /// <param name="obj">对象实例</param> /// <param name="isStr">是否全部输出为字符串</param> /// <param name="ignores">忽略输出的属性(不区分大小写)</param> /// <returns>Json字符串</returns> public static string ToJson(this Object obj, bool isStr = false, params string[] ignores) { switch (obj) { //TODO:特殊类型转换添加到此处 case Guid value: return $"\"{value.ToString()}\""; case IList value: return IListToJson(value, isStr, ignores); case IDictionary value: return IDictionaryToJson(value, isStr, ignores); case Object value: return ObjectToJson(obj, isStr, ignores); default: throw new NotImplementedException("无法识别对象!"); } } #region 基础转换 /// <summary> /// 转换值为Json字符串 /// </summary> /// <param name="value">值</param> /// <param name="isStr">是否转为字符串</param> /// <param name="ignores">忽略字段</param> /// <returns></returns> private static string ValueToJson(this object value, bool isStr = false, params string[] ignores) { if (null == value) return "null"; string str_property = string.Empty; var type = value.GetType(); switch (type.BaseType.Name) { case "ValueType": case "Object": //获取此属性类型标识 TypeCode code = Convert.GetTypeCode(value); switch (code) { case TypeCode.Empty: str_property += "null"; break; case TypeCode.Object: str_property += ToJson(value, isStr, ignores); break; case TypeCode.Boolean: str_property += isStr ? $"\"{value.ToString().ToLower()}\"" : value.ToString().ToLower(); break; case TypeCode.Int32: case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.Int64: case TypeCode.UInt64: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: str_property += isStr ? $"\"{value}\"" : value; break; case TypeCode.Char: str_property += $"\"{(((Char)value != Char.MinValue) ? value : string.Empty)}\""; break; case TypeCode.String: str_property += $"\"{(((String)value != String.Empty) ? value : string.Empty)}\""; break; case TypeCode.DateTime: str_property += $"\"{Convert.ToDateTime(value).ToString("yyyy-MM-dd HH:mm:ss")}\""; break; case TypeCode.DBNull: default: throw new NotImplementedException("无法识别对象!"); } break; case "Enum": str_property += isStr ? $"\"{value.GetHashCode()}\"" : value.GetHashCode().ToString(); break; default: str_property += ToJson(value, isStr, ignores); break; } return str_property; } /// <summary> /// 对象转换为Json /// </summary> /// <param name="obj">对象实例</param> /// <param name="isStr"></param> /// <param name="ignores">忽略输出的属性</param> /// <returns>Json字符串</returns> private static string ObjectToJson(this Object obj, bool isStr = false, params string[] ignores) { PropertyInfo[] properties = obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); //Object 头 StringBuilder builder = new StringBuilder("{"); foreach (var property in properties) { if (null != ignores && ignores.Length > 0 && ignores.Any(g => g.ToLower() == property.Name.ToLower())) { continue; } else { //此属性json表示字符 string str_property = string.Empty; //属性名称格式 str_property = $"\"{property.Name}\":"; //获取此属性值 Object value = property.GetValue(obj); //添加此属性值 str_property += ValueToJson(value, isStr, ignores); //是否添加间隔符 builder.Append(str_property + ','); } } //有内容时去除多余间隔符 if (properties.Length > 0 && builder.Length > 1) { //去除多余间隔符 builder.Remove(builder.Length - 1, 1); } //Object 尾 builder.Append("}"); return builder.ToString(); } /// <summary> /// 组类型转换为Json /// </summary> /// <param name="list">组类型</param> /// <param name="isStr"></param> /// <param name="ignores">忽略输出的属性</param> /// <returns>Json字符串</returns> private static string IListToJson(this IList list, bool isStr = false, params string[] ignores) { StringBuilder builder = new StringBuilder("["); //转换值为json字符串 foreach (var value in list) builder.Append(ValueToJson(value, isStr, ignores) + ','); //有内容时去除多余间隔符 if (list.Count > 0) { //去除多余间隔符 builder.Remove(builder.Length - 1, 1); } //添加结尾符 builder.Append("]"); return builder.ToString(); } /// <summary> /// 字典类型转换为Json字符串 /// </summary> /// <param name="dictionary"></param> /// <param name="isStr"></param> /// <param name="ignores"></param> /// <returns>Json字符串</returns> private static string IDictionaryToJson(this IDictionary dictionary, bool isStr = false, params string[] ignores) { StringBuilder builder = new StringBuilder("["); foreach (var key in dictionary.Keys) { var value = dictionary[key]; //外边界 builder.Append("["); //转换key builder.Append(ValueToJson(key, isStr, ignores)); //分隔 builder.Append(","); //转换value builder.Append(ValueToJson(value, isStr, ignores)); //尾边界 builder.Append("],"); } //有内容时去除多余间隔符 if (dictionary.Count > 0) { //去除多余间隔符 builder.Remove(builder.Length - 1, 1); } builder.Append("]"); return builder.ToString(); } #endregion } }
Json转对象
using System; using System.Collections; using System.Collections.Generic; using System.Reflection; namespace JSON { /* Json转obj * 得到转换类型 * 解析Json,解析为此对象一个属性跟一个此属性的字符串,为object时,循环解析(object) * * */ /// <summary> /// Json转化为Object /// </summary> public static class ToObjectEX { /* * Object Json: {key:value} [value,value] [[key,value],[key,value]] value */ /// <summary> /// 转换Json为指定类型 /// </summary> /// <typeparam name="T">对象类型</typeparam> /// <param name="objectJson">Object的Json字符串</param> /// <returns>指定类型实例</returns> public static T ToObject<T>(string objectJson) { return (T)ToObject(typeof(T), objectJson); } /* * Object Json: {key:value} [value,value] [[key,value],[key,value]] value */ /// <summary> /// 转换Json为指定类型 /// </summary> /// <param name="type">对象类型</param> /// <param name="objectJson">Object的Json字符串</param> /// <returns>指定类型实例</returns> public static object ToObject(Type type, string objectJson) { switch (type.Name) { case "Object": //TODO:无法解析类型为Object的实例[默认转为字符串] return objectJson; case "Guid": return new Guid(objectJson.Trim('"')); case "List`1": return JsonToIList(type, objectJson); case "Dictionary`2": return JsonToIDictionary(type, objectJson); default: if (type.BaseType.Name == "Array") { return JsonToArray(type, objectJson); } else { return JsonToObject(type, objectJson); } } } #region 基础转换 /* * Value Json: value */ /// <summary> /// 转换Json为指定类型值 /// </summary> /// <param name="type">对象类型</param> /// <param name="valueJson">值的Json字符串</param> /// <returns>指定类型实例</returns> private static object JsonToValue(Type type, string valueJson) { if ("null" != valueJson) { valueJson = RemoveSE(valueJson); //此属性的类型 TypeCode typeCode = Type.GetTypeCode(type); switch (typeCode) { case TypeCode.Object: return ToObject(type, valueJson); case TypeCode.Char: if (string.IsNullOrEmpty(valueJson)) { return Char.MinValue; } goto case TypeCode.Single; case TypeCode.String: if (string.IsNullOrEmpty(valueJson)) { return string.Empty; } goto case TypeCode.Single; case TypeCode.DateTime: case TypeCode.Boolean: case TypeCode.Int32: case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.Int64: case TypeCode.UInt64: case TypeCode.Double: case TypeCode.Decimal: case TypeCode.Single: if (!string.IsNullOrEmpty(valueJson)) { return Convert.ChangeType(valueJson, typeCode); } break; case TypeCode.Empty: case TypeCode.DBNull: default: throw new NotImplementedException("未知类型"); } } return default; } /* * Object Json: {key:value} */ /// <summary> /// 转换Json为指定类型 /// </summary> /// <param name="type">对象类型</param> /// <param name="objectJson">Json字符串</param> /// <returns>指定类型实例</returns> private static object JsonToObject(Type type, string objectJson) { //创建此类型实例 var obj = Activator.CreateInstance(type); //获取对象类型 PropertyInfo[] properties = obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); //解析ObjectJson Dictionary<string, string> pairs = ParsingObjectJson(objectJson); //属性不为空 和 解析字符串不为空 if (properties.Length > 0 && pairs.Count > 0) { //此对象的所有属性 foreach (var property in properties) { //Json是否有此属性 if (pairs.ContainsKey(property.Name)) { //没有此属性 或 Value为空 跳过 if (!pairs.ContainsKey(property.Name) || string.IsNullOrEmpty(pairs[property.Name])) continue; //转换value为类型属性值 property.SetValue(obj, JsonToValue(property.PropertyType, pairs[property.Name])); } } } else { obj = default; } return obj; } /* * List Json: [value,value] */ /// <summary> /// 转换Json为指定类型组 /// </summary> /// <param name="type">对象类型</param> /// <param name="ilistJson">List的Json字符串</param> /// <returns>指定类型组实例</returns> private static object JsonToIList(Type type, string ilistJson) { if (!string.IsNullOrEmpty(ilistJson) && ilistJson != "[]" && ilistJson != "null") { //初始化此IList var ilist = (IList)Activator.CreateInstance(type); //获取此实例的对象 var tempType = type.GenericTypeArguments[0]; //解析 List<string> list = ParsingIListJson(ilistJson); if (list.Count > 0) { foreach (var value in list) { ilist.Add(JsonToValue(tempType, value)); } return ilist; } } return default; } /* * Array Json: [value,value] */ /// <summary> /// 转换Json为指定类型组 /// </summary> /// <param name="type">对象类型</param> /// <param name="arrayJson">Array的Json字符串</param> /// <returns>指定类型组实例</returns> private static object JsonToArray(Type type, string arrayJson) { if (!string.IsNullOrEmpty(arrayJson) && arrayJson != "[]" && arrayJson != "null") { //获取程序集信息(除类型外) string aqn = new string(type.AssemblyQualifiedName.ToCharArray().SplitFirst(out char[] first, type.FullName.ToCharArray())); //获取数组维度 int num = type.Name.ToCharArray().Same(c => c == ']'); //获取数组类型 type.Name.ToCharArray().SplitFirst(out char[] arrType, '[', ']'); //数组类型名称 String typeName = new String(arrType); //恢复维度 for (int i = 0; i < num - 1; i++) { typeName += "[]"; } //初始化数组类型 Type objType = Type.GetType(type.Namespace + '.' + typeName + aqn); //解析数组 List<string> list = ParsingIListJson(arrayJson); //创建数组,按返回值长度创建 var iArr = Array.CreateInstance(objType, list.Count); //转换为数组值 for (int i = 0; i < list.Count; i++) { iArr.SetValue(JsonToValue(objType, list[i]), i); } return iArr; } return default; } /* * 键值对 Json: [[key,value],[key,value]] */ /// <summary> /// 转换Json为指定类型键值对 /// </summary> /// <param name="type">对象类型</param> /// <param name="idictionaryJson">键值对的Json字符串</param> /// <returns>指定类型键值对实例</returns> private static object JsonToIDictionary(Type type, string idictionaryJson) { if (!string.IsNullOrEmpty(idictionaryJson) && idictionaryJson != "[]" && idictionaryJson != "null") { //Key 类型 Type keyType = type.GenericTypeArguments[0]; //Value 类型 Type valueType = type.GenericTypeArguments[1]; //初始化一个此类型实例 var dic = (IDictionary)Activator.CreateInstance(type); //解析键值对json Dictionary<string, string> pairs = ParsingIDictionaryJson(idictionaryJson); //键值对赋值 foreach (var keyValue in pairs) { dic.Add(JsonToValue(keyType, keyValue.Key), JsonToValue(valueType, keyValue.Value)); } return dic; } return default; } #endregion #region Core /// <summary> /// 解析ObjectJson为键值对(Ok-2020年7月3日18点37分)[Core] /// </summary> /// <param name="objectJson">实例Json</param> /// <returns>实例的属性与值键值对</returns> private static Dictionary<string, string> ParsingObjectJson(string objectJson) { Dictionary<string, string> pairs = new Dictionary<string, string>(); if (objectJson != "{}" && objectJson != "null") { string[] jsonArr = objectJson.Split(new string[] { "\":" }, StringSplitOptions.RemoveEmptyEntries); if (null != jsonArr && jsonArr.Length > 0) { int signLen = -1; //标志长度 string key = string.Empty, //key value = string.Empty; //value foreach (var str in jsonArr) { signLen += GetSameHead(str); signLen -= GetSameTail(str); //获取key value char[] resTempValue = str.ToCharArray().SplitLast(out char[] resTempKey, ',', '\"'); if (null != resTempValue && null != resTempKey) { if (signLen == 0) { pairs[key] += new string(resTempValue); key = new string(resTempKey); pairs.Add(key, string.Empty); } else { pairs[key] += str + "\":"; } } else { if (pairs.Count > 0) { pairs[key] += str + "\":"; } else { str.ToCharArray().SplitLast(out char[] last, '{', '\"'); key = new String(last); pairs.Add(key, string.Empty); } } } if (pairs.Count >= 1) { //清除最后一次添加的 \": pairs[key] = pairs[key].Remove(pairs[key].Length - 3); } } } return pairs; } /* * IList Json: [value,value] [[value,value],[value,value]] [[[value,value],[value,value]],[[value,value]]] */ /// <summary> /// 解析IListJson为组,支持多维数组(分割成单个实例Json,Ok 2020年7月4日15点01分)[Core] /// </summary> /// <param name="ilistJson">组Json</param> /// <returns>解析后的值组</returns> private static List<string> ParsingIListJson(string ilistJson) { List<string> list = new List<string>(); int signLen = 0; //标志长度 //去除头尾 string temp = ilistJson.Remove(0, 1); temp = temp.Remove(temp.Length - 1, 1); string[] arr = temp.Split(','); string value = string.Empty; foreach (var str in arr) { signLen += GetSameHead(str); signLen -= GetSameTail(str); value += str; if (signLen == 0) { list.Add(value); value = string.Empty; } else { value += ','; } } return list; } /* * 键值对 Json: [[key,value],[key,value]] */ /// <summary> /// 解析IDictionaryJson为键值对 /// </summary> /// <param name="idictionaryJson">键值对Json</param> /// <returns>解析后的键值对</returns> private static Dictionary<string, string> ParsingIDictionaryJson(string idictionaryJson) { Dictionary<string, string> pairs = new Dictionary<string, string>(); var arr = ParsingIListJson(idictionaryJson); foreach (var item in arr) { var tempArr = ParsingIListJson(item); if (tempArr.Count == 2) { pairs.Add(tempArr[0], tempArr[1]); } else { pairs.Add(tempArr[0], string.Empty); } } return pairs; } /// <summary> /// 获取相同头数量 /// </summary> /// <param name="jsonValue"></param> /// <returns></returns> private static int GetSameHead(string jsonValue) { int resNum = 0; resNum += jsonValue.ToCharArray().Same(c => c == '{'); resNum += jsonValue.ToCharArray().Same(c => c == '['); return resNum; } /// <summary> /// 获取相同结尾数量 /// </summary> /// <param name="jsonValue"></param> /// <returns></returns> private static int GetSameTail(string jsonValue) { int resNum = 0; resNum += jsonValue.ToCharArray().Same(c => c == '}'); resNum += jsonValue.ToCharArray().Same(c => c == ']'); return resNum; } /// <summary> /// 删除首尾 \" 符 /// </summary> /// <param name="str"></param> /// <returns></returns> private static string RemoveSE(string str) { if (str.StartsWith("\"")) { str = str.Remove(0, 1); } if (str.EndsWith("\"")) { str = str.Remove(str.Length - 1, 1); } return str; } #endregion } }

浙公网安备 33010602011771号