.net中如何实现json转化时只处理部分属性?

来源:互联网 发布:java中jedis方法 编辑:程序博客网 时间:2024/05/01 23:32

把对象转化为json字符串,很常用,但如果因为现在大部分项目都是用了ORM映射,导致一个对象的属性特别多,如果前台只需要部分属性如何实现?

当然最简单是所有属性都json化,前台只处理需要的属性,多余的不管。那有没有一种方式可以实现,对于同一种类型,按照前台的需要只处理json需要的属性呢?

.Net中把对象转为json字符串主要有四种,具体参考

1自己转化灵活,但难度大,能实现。

2使用Newtonsoft.Json,看了一下官方文档,似乎不能实现,能忽略默认,空值等属性,也可以控制json时输出那些属性,但需要使用特性,也就是说,对于指定的类型,json输出的属性是确定的,不能动态改变。

具体可参考

3使用JavaScriptSerializer类,查看了官方文档,没找到方法,不能实现

4也是使用的是特性,没找到方法,不能实现。


没有现成的方法,也就只能自己实现了。我们知道把对象转化为json字符串,核心自然是使用反射得到需要的属性和属性的值。但如果属性是一个类对象呢?,数组或者是泛型呢?

另外如果字符串中包含特殊字符如何处理?

于是自己也就实现了一个简单的

  /// <summary>        /// 把对象转化为json字符串        /// </summary>        /// <typeparam name="T">需要转化的对象的类型</typeparam>        /// <param name="t">需要转化的对象</param>        /// <param name="propertyInfos">需要转换的字段列表,用逗号分隔</param>        /// <returns></returns>        public static string ConvertFromModeTojson<T>(T t, string propertyInfos) where T : class        {            string[] cols = propertyInfos.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);            System.Text.StringBuilder sb = new System.Text.StringBuilder(300);            string result = "{";            foreach (string col in cols)            {                string str = GetOneProperty<T>(t, col);                sb.Append(str);            }            result += sb.ToString().TrimEnd(',');            result += "}";            return result;        }        private static string GetOneProperty<T>(T t, string pname) where T : class        {            Type type = t.GetType();            PropertyInfo pinfo = type.GetProperty(pname);//使用反射获得属性            if (pinfo != null)            {                object v = pinfo.GetValue(t, null);//使用反射获得属性的值                string tt = PropertyTypeValue(pinfo.PropertyType, v, pname);                return tt;            }            else            {                throw new Exception("不存在属性" + pname);            }        }        /// <summary>        /// 按照数字格式输入的类型        /// </summary>        private static readonly List<Type> TypeNumCodeList = new List<Type>{      { typeof(sbyte)},                { typeof(sbyte?)},                { typeof(short)},                { typeof(short?)},                { typeof(ushort)},                { typeof(ushort?)},                { typeof(int)},                { typeof(int?)},                { typeof(byte)},                { typeof(byte?)},                { typeof(uint)},                { typeof(uint?)},                { typeof(long)},                { typeof(long?)},                { typeof(ulong)},                { typeof(ulong?)},                { typeof(float)},                { typeof(float?)},                { typeof(double) },                { typeof(double?)},                  { typeof(decimal)},                { typeof(decimal?)},                  { typeof(bool)},                { typeof(bool?)}          };        /// <summary>        /// 按照文字格式输入的类型        /// </summary>        private static readonly List<Type> TypeStrCodeList = new List<Type>{                 { typeof(char)},                { typeof(char?)},                   { typeof(DateTime)},                { typeof(DateTime?)}         };        /// <summary>        /// 根据字段类型进行罗列,显然不能处理所有的类型,也没有处理字段是数组,对象的情况        /// </summary>        /// <param name="propertytype"></param>        /// <param name="value"></param>        /// <param name="propertyName"></param>        /// <returns></returns>        private static string PropertyTypeValue(Type propertytype, object value, string propertyName)        {            string valueStr = value != null ? value.ToString() : "";            string returnStr = "";            if (TypeNumCodeList.Contains(propertytype))            {                if (!string.IsNullOrEmpty(valueStr))//忽略掉空值                {                    returnStr = string.Format("\"{0}\":{1},", propertyName, valueStr);                }            }            else if (TypeStrCodeList.Contains(propertytype))            {                if (!string.IsNullOrEmpty(valueStr))//忽略掉空值                {                    returnStr = string.Format("\"{0}\":\"{1}\",", propertyName, valueStr);                }            }            else if (propertytype == typeof(string))            {                if (!string.IsNullOrEmpty(valueStr))//忽略掉空值,并处理字符串中的特殊字符                {                    returnStr = string.Format("\"{0}\":\"{1}\",", propertyName, String2Json(valueStr));                }            }            else  //对象,数组等不能处理,                             {                returnStr = string.Format("\"{0}\":\"{1}\",", propertyName, String2Json(valueStr));            }                         return returnStr;        }        /// <summary>          /// 过滤特殊字符          /// </summary>          /// <param name="s"></param>          /// <returns></returns>          private static string String2Json(string s)        {            StringBuilder sb = new StringBuilder();            for (int i = 0; i < s.Length; i++)            {                char c = s.ToCharArray()[i];                switch (c)                {                    case '\"':                        sb.Append("\\\""); break;                    case '\\':                        sb.Append("\\\\"); break;                    case '/':                        sb.Append("\\/"); break;                    case '\b':                        sb.Append("\\b"); break;                    case '\f':                        sb.Append("\\f"); break;                    case '\n':                        sb.Append("\\n"); break;                    case '\r':                        sb.Append("\\r"); break;                    case '\t':                        sb.Append("\\t"); break;                    /*  case '<':                          sb.Append("<"); break;                      case '>':                          sb.Append(">"); break;*/                    default:                        if ((c >= 0 && c <= 31) || c == 127)//在ASCⅡ码中,第0~31号及第127号(共33个)是控制字符或通讯专用字符                        {                        }                        else                        {                            sb.Append(c);                        }                        break;                }            }            return sb.ToString();        }



很显然,这个实现有很大的问题,字符串中包含的特殊字符不一定处理完了,泛型,数组等属性都没有处理,但是简单对象还是可以处理的。

既然Newtonsoft.Json是开源的,那能不能利用它实现呢?

于是使用Newtonsoft.Json改进了以上代码

 private static readonly List<Type> TypeCodeList = new List<Type>{                          { typeof(char)},                { typeof(char?)},                { typeof(bool)},                { typeof(bool?)},                { typeof(sbyte)},                { typeof(sbyte?)},                { typeof(short)},                { typeof(short?)},                { typeof(ushort)},                { typeof(ushort?)},                { typeof(int)},                { typeof(int?)},                { typeof(byte)},                { typeof(byte?)},                { typeof(uint)},                { typeof(uint?)},                { typeof(long)},                { typeof(long?)},                { typeof(ulong)},                { typeof(ulong?)},                { typeof(float)},                { typeof(float?)},                { typeof(double) },                { typeof(double?)},                { typeof(DateTime)},                { typeof(DateTime?)},                { typeof(DateTimeOffset)},                { typeof(DateTimeOffset?)},                { typeof(decimal)},                { typeof(decimal?)},                { typeof(Guid)},                { typeof(Guid?)},                { typeof(TimeSpan)},                { typeof(TimeSpan?)},                { typeof(Uri)},                { typeof(string)},                { typeof(byte[])}, { typeof(DBNull)}            };        /// <summary>        /// 把对象转化为json字符串,依然不能处理属性是泛型,数组,对象等类型        /// </summary>        /// <typeparam name="T">需要转化的对象的类型</typeparam>        /// <param name="t">需要转化的对象</param>        /// <param name="propertyInfos">需要转换的字段列表,用逗号分隔</param>        /// <returns></returns>        public static string ConvertFromModeTojson<T>(T t, string propertyInfos) where T : class        {            StringWriter sw = new StringWriter();            using (JsonTextWriter writer = new JsonTextWriter(sw))            {                writer.WriteStartObject();                string[] cols = propertyInfos.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);                foreach (string col in cols)                {                    Type type = t.GetType();                    PropertyInfo pinfo = type.GetProperty(col);//使用反射获得属性                    if (pinfo != null)                    {                        object v = pinfo.GetValue(t, null);//使用反射获得属性的值                        Type pinfoType = pinfo.PropertyType;                        if (TypeCodeList.Contains(pinfoType))                        {                            writer.WritePropertyName(col);                            writer.WriteValue(v);                        }                        else                        { //其他类型的忽略,避免异常                        }                    }                    else                    {                        throw new Exception("不存在属性" + col);                    }                }                writer.WriteEndObject();                writer.Flush();            }            string jsonText = sw.GetStringBuilder().ToString();            return jsonText;        }


0 0
原创粉丝点击