zoukankan      html  css  js  c++  java
  • 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//等于张三
  • 相关阅读:
    centos6.5 源码安装 gtk 环境
    世界的复杂性
    将 shell 脚本打包到 rpm 包中
    使用 ipdb 调试 Python
    shell 处理 文件名本身带星号的情况
    如果可以更更完善,为什么不呢?
    比较有名的开源项目
    各种小工具合集
    各种版本对应关系
    dns相关
  • 原文地址:https://www.cnblogs.com/Thancoo/p/jsonfillobject.html
Copyright © 2011-2022 走看看