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//等于张三

 

posted on 2017-02-01 21:56  Thancoo  阅读(587)  评论(0编辑  收藏  举报

导航