• 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//等于张三
  • 相关阅读:
    ServerSuperIO 3.5版本的体系结构,以及未来规划的几点思考
    《连载 | 物联网框架ServerSuperIO教程》- 18.集成OPC Client,及使用步骤。附:3.5 发布与更新说明。
    《连载 | 物联网框架ServerSuperIO教程》- 17.集成Golden实时数据库,高并发保存测点数据。附:3.4 发布与版本更新说明。
    《连载 | 物联网框架ServerSuperIO教程》- 16.集成OPC Server,及使用步骤。附:3.3 发布与版本更新说明。
    [祝贺] 东方国信集团的钢铁大数据和工业节能两个案例入选工信部工业互联网优秀案例
    《连载 | 物联网框架ServerSuperIO教程》- 15.数据持久化接口的使用。附:3.2发布与版本更新说明。
    物联网建设中通讯互联层的终极解决方案
    hadoop 2.7.2 + zookeeper 高可用集群部署
    开源物联网框架ServerSuperIO 3.0正式发布(C#),跨平台:Win&Win10 Iot&Ubuntu&Ubuntu Mate,一套设备驱动跨平台挂载,附:开发套件和教程。
    《连载 | 物联网框架ServerSuperIO教程》- 14.配制工具介绍,以及设备驱动、视图驱动、服务实例的挂载
  • 原文地址:https://www.cnblogs.com/Thancoo/p/jsonfillobject.html
Copyright © 2020-2023  润新知