Json填充Object工具
using System; using System.Collections.Generic; using System.Text.RegularExpressions; using Campaign.Commons.ConstParam; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace Campaign.Commons.ExtMethod { public static class JsonParamsHelper { /// <summary> /// 替换类中同名的属性的值,并返回填充后的类 /// </summary> /// <typeparam name="T">要填充的类型</typeparam> /// <param name="frameobj">要填充的参数</param> /// <param name="parms">包含对象的参数的一维json</param> /// <param name="extendsParams">扩展参数,针对params中的模板进行替换($索引$)</param> /// <returns>填充后的frameobj</returns> public static T FrameFilling<T>(this T frameobj, string parms, params object[] extendsParams) where T : class, new() { try { var pas = JsonConvert.DeserializeObject<dynamic>(parms); return LoopFilling(frameobj, pas, extendsParams); } catch { return null; } } #region 简化工具 private static T LoopFilling<T, TP>(T obj, TP param, object[] extparams = null, ReplaceModeEnum replaceMode = ReplaceModeEnum.FullPettern) where T : new() where TP : JObject { try { foreach (var oo in obj.GetType().GetProperties()) { if (oo.PropertyType.IsValueType || oo.PropertyType.Name == "String") { var month = oo.GetSetMethod(); if (param[oo.Name] == null || param[oo.Name].Type == JTokenType.Array || param[oo.Name].Type == JTokenType.Object) continue; if (!month.IsPublic || param[oo.Name] == null) continue; month.Invoke(obj, new[] { param[oo.Name].PartternRep(RegexPatterns.WECHAT_TEMP_MESSAGE_ARGS_PATTERN, extparams, oo.PropertyType) }); } else if (oo.PropertyType.GetInterface("IEnumerable") != null) { //是集合类型 //泛型集合 var _enum = oo.PropertyType; if (_enum.GetInterface("IList") != null) { //判断参数中的该参数是否为数组 if (param[oo.Name] != null && param[oo.Name].Type == JTokenType.Array) { //创建泛型类型 var tps = _enum.GetGenericArguments()[0]; if (tps.IsGenericType) throw new Exception("目前泛型只支持一层嵌套!"); var addmethod = _enum.GetMethod("Add"); var list = oo.GetValue(obj); if (list == null) { var tp = typeof(List<>); var gtp = tp.MakeGenericType(tps); list = Activator.CreateInstance(gtp); //只允许一层泛型,泛型嵌套不给予考录。 oo.GetSetMethod().Invoke(obj, new[] { list }); } //o可能是基础类型,或者是Object //如果是基础类型,直接加,如果是Object,还需要反射,获取Object中的值 if (tps.IsValueType || tps.Name == "String") { foreach (var ppp in param[oo.Name]) { addmethod.Invoke(list, new[] { ppp.PartternRep(RegexPatterns.WECHAT_TEMP_MESSAGE_ARGS_PATTERN, extparams, tps) }); } } else if (tps.IsClass) { var undertypeproperty = tps.GetProperties(); foreach (var o in param[oo.Name]) { var udi = Activator.CreateInstance(tps); foreach (var i in undertypeproperty) { if (i.PropertyType.IsValueType || i.PropertyType.Name == "String") { i.GetSetMethod() .Invoke(udi, new[] { o[i.Name].PartternRep( RegexPatterns.WECHAT_TEMP_MESSAGE_ARGS_PATTERN, extparams, i.PropertyType) }); } else { LoopFilling(udi, (JObject)o, extparams); } } addmethod.Invoke(list, new[] { udi }); } } } } else if (_enum.GetInterface("IDictionary") != null) { if (param[oo.Name] == null || param[oo.Name].Type != JTokenType.Object) continue; var gentypes = _enum.GetGenericArguments(); //如果Key不是String类型的话抛出异常 if (gentypes[0].Name != "String") throw new Exception("Key只能为string类型。"); dynamic idic = oo.GetValue(obj); if (idic == null) { var dct = typeof(Dictionary<,>); idic = Activator.CreateInstance(dct.MakeGenericType(_enum.GetGenericArguments())); oo.GetSetMethod().Invoke(obj, new object[] { idic }); } foreach (var n in (JObject)param[oo.Name]) { dynamic key = n.Key; dynamic value = idic.ContainsKey(n.Key) ? idic[n.Key] : Activator.CreateInstance(gentypes[1]); LoopFilling(value, (JObject)n.Value, extparams); if (idic.ContainsKey(n.Key)) idic[key] = value; else idic.Add(key, value); } } } else if (oo.PropertyType.IsClass) { if (param[oo.Name] == null || param[oo.Name].Type != JTokenType.Object) continue; var _obj = oo.GetValue(obj); if (_obj == null) { _obj = Activator.CreateInstance(oo.PropertyType); oo.GetSetMethod().Invoke(obj, new[] { _obj }); } LoopFilling(oo.GetValue(_obj), (JObject)param[oo.Name], extparams); } } } catch (Exception e) { e.Log("Json填充实体失败:"); } return obj; } private static object PartternRep(this JToken token, string targ, object[] parms, Type tagType, ReplaceModeEnum replaceMode = ReplaceModeEnum.FullPettern) { //根据匹配的模式进行字符串处理 if (!tagType.IsValueType && tagType.Name != "String") throw new Exception("T只能是简单类型(值类型或String)!"); if (!Regex.IsMatch(token.Value<string>(), targ)) return Convert.ChangeType(token, tagType); if (parms == null) { throw new Exception("没有提供需要的参数"); } //如果多种匹配方式,则优先级如下:NamingPettern>PartPettern>FullPettern string pattern = targ; switch (replaceMode) { case ReplaceModeEnum.FullPettern: if (Regex.IsMatch(targ, "\\^\\w+\\$")) break; pattern = string.Concat("^", targ, "$"); break; case ReplaceModeEnum.NamingPettern://以后再做吧 break; case ReplaceModeEnum.PartPettern: if (!Regex.IsMatch(targ, "\\^\\w+\\$")) break; pattern = targ.Substring(1, targ.Length - 2); break; case (ReplaceModeEnum.FullPettern|ReplaceModeEnum.NamingPettern)://以后再做吧 /* 查看所有的参数,寻找类类型的参数, */ break; case (ReplaceModeEnum.PartPettern | ReplaceModeEnum.NamingPettern)://以后再做吧 break; case (ReplaceModeEnum.FullPettern | ReplaceModeEnum.PartPettern)://依然是PartPettern if (!Regex.IsMatch(targ, "\\^\\w+\\$")) break; pattern = targ.Substring(1, targ.Length - 2); break; } var mtcs = Regex.Matches(token.Value<string>(), pattern, RegexOptions.CultureInvariant); var paridx = int.Parse(mtcs[0].Groups["rpidx"].Value); if (paridx >= parms.Length || paridx < 0) throw new Exception("动态参数索引越界!"); if (parms[paridx] == null) throw new Exception("提供的参数不能为Null"); return Convert.ChangeType(parms[paridx], tagType); } public static bool IsAnonymousType(this Type tp) { return tp.Name.Contains("AnonymousType"); } #endregion } }
//使用方法
public class a{
public string name{get;set;}
public string sex{get;set;}
}
a.FrameFilling("{\"name\":\"张三\"}")
a.name//等于张三