C# JSON转化

C# 对象转JSON,效率是系统自带的转化器的十倍,每次转换提供回调函数,可自定义转化结果,回调函数提供路径、属性和字段,可对转化的属性和字段进行特性查找,可对返回数据劫持。一般用于返回加密

    public class ActionJson
    {
        public class CryptPath
        {
            public string Path { get; set; }
            public int CryptType { get; set; }

            public CryptPath()
            {
                this.CryptType = 1;
            }
        }

        /// <summary>
        /// 如果需要对路径进行加密,返回中添加对象 CryptPaths
        /// 如果需要参数辅助加密,返回中添加对象CryptParams
        /// </summary>
        /// <param name="func"></param>
        /// <returns></returns>
        public ActionResult Out(Func<object> func)
        {
            var jm = new JsonMessage();
            var ret = default(object);
            var json = string.Empty;

            try
            {
                ret = func();
                jm.Flag = true;
            }
            catch(Exception e)
            {
                if (e.InnerException != null)
                    jm.Message = e.InnerException.Message;
                else
                    jm.Message = e.Message;
            }

            if (ret == null || jm.Flag == false)
            {
                jm.Data = null;
                json = Serialize(jm,null,null);
            }
            else
            {
                var path = ret.GetType().GetProperty("CryptPaths")?.GetValue(ret);
                var param = ret.GetType().GetProperty("CryptParams")?.GetValue(ret);
                var paths = new List<string>();

                if(path != null || param != null)
                {
                    ret = ret.GetType().GetProperty("Data")?.GetValue(ret);
                    if (ret == null)
                        throw new Exception("必须用Data封装返回的数据");
                }

                if (path != null)
                    paths = ((IEnumerable<CryptPath>)path).Select<CryptPath, string>(o => o.Path).ToList();

                json = Serialize(ret, param == null ? null : (object[])param, (_path, _val, _porf, _param) => 
                {
                    return _val;
                });
            }

            HttpContext.Current.Response.ContentType = "application/json";
            HttpContext.Current.Response.Write(json);
            HttpContext.Current.Response.End();

            return new EmptyResult();
        }

        public static string Serialize(object obj, object[] cry, Func<string, object, object, object[], object> func = null)
        {
            return MakeObj(obj, "out", null, cry, func)?.ToString();
        }

        private static string ConvertString(object obj)
        {
            return obj.ToString().Replace("\r", "\\r").Replace("\n", "\\n").Replace("\"", "\\\"").Replace("\t", "\\t");
        }

        private static string ConvertDate(object obj)
        {
            return ((DateTime)obj).ToString("yyyy-MM-dd HH:mm:ss");
        }

        private static string MakeArr(string path, object obj, object[] cry, Func<string, object, object, object[], object> func)
        {
            var bremove = false;
            var sb = new StringBuilder("[");
            foreach (var item in (obj as System.Collections.IEnumerable))
            {
                bremove = true;
                sb.Append($"{MakeObj(item, $"{path}.$", null, cry, func)},");
            }
            if (bremove)
                sb = sb.Remove(sb.Length - 1, 1);

            sb.Append("]");
            return sb.ToString();
        }

        private static string MakeDict(string path, object obj, object[] cry, Func<string, object, object, object[], object> func)
        {
            var sb = new StringBuilder("{");
            var bremove = false;

            foreach (var item in (obj as System.Collections.IDictionary))
            {
                bremove = true;
                var ikey = item.GetType().GetProperty("Key").GetValue(item, null);
                var ival = item.GetType().GetProperty("Value").GetValue(item, null);
                sb.Append($"\"{ikey}\":{ MakeObj(ival, $"{path}.{ikey}",null, cry, func)},");
            }

            if (bremove)
                sb = sb.Remove(sb.Length - 1, 1);
            bremove = false;
            sb.Append("}");
            return sb.ToString();
        }

        private static object MakeObj(object obj, string path,object fiopi, object[] cry, Func<string, object, object, object[], object> func = null)
        {
            if (obj is Int32? || obj is double? || obj is float? || obj is decimal? 
                || obj is Boolean? || obj is short? || obj is Int16? || obj is Int64?)
            {
                if (func == null) return obj;
                else return func(path, obj, fiopi, cry);
            }
            else if (obj is string || obj is char?)
            {
                if (func == null) return $"\"{ConvertString(obj)}\"";
                else return func(path, $"\"{ConvertString(obj)}\"", fiopi, cry);
            }
            else if(obj is Boolean?)
            {
                if (func == null) return ((Boolean)obj) ? "true" : "false";
                else return func(path, ((Boolean)obj) ? "true" : "false", fiopi, cry);
            }
            else if (obj is DateTime?)
            {
                if (func == null) return $"\"{ConvertDate(obj)}\"";
                else return func(path, $"\"{ConvertDate(obj)}\"", fiopi, cry);
            }
            else if (obj == null || obj == DBNull.Value)
            {
                if (func == null) return "null";
                else return func(path, "null", fiopi, cry);
            }
            else if (obj.GetType().IsEnum)
            {
                if (func == null) return (int)obj;
                else return func(path, (int)obj, fiopi, cry);
            }
            else if (obj is System.Collections.IDictionary)
                return MakeDict(path, obj, cry, func);
            else if (obj is System.Collections.IEnumerable)
                return MakeArr(path, obj, cry, func);

            var sb = new StringBuilder("{");

            foreach (var fi in obj.GetType().GetFields())
                sb.AppendFormat("\"{0}\":{1},", fi.Name, MakeObj(fi.GetValue(obj), $"{path}.{fi.Name}", fi, cry, func));

            foreach (var pi in obj.GetType().GetProperties())
                sb.AppendFormat("\"{0}\":{1},", pi.Name, MakeObj(pi.GetValue(obj, null), $"{path}.{pi.Name}", pi, cry, func));

            var ret = sb.ToString();
            ret = ret.Remove(ret.Length - 1);
            ret += "}";
            return ret;
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值