IList嵌套转JSON问题

sharp_scr 2017-04-24 12:32:13

项目里面有2个类A和B,类B以IList或者List的形式作为类A的成员变量,具体关系如下:

类A:
namespace EB.Common
{
public class A
{
private string _id;
private string _name;
private string _code;
IList<EB.Common.B> _detail;

public string ID
{
set { _id = value; }
get { return _id; }
}

public string Name
{
set { _name = value; }
get { return _name; }
}

public string Code
{
set { _code = value; }
get { return _code; }
}

public IList<EB.Common.B> Detail
{
set { _detail = value; }
get { return _detail; }
}

}
}


类B:
namespace EB.Common
{
public class B
{
private string _id;
private int _num;
private string _type;

public string ID
{
set { _id = value; }
get { return _id; }
}

public int Num
{
set { _num = value; }
get { return _num; }
}

public string Type
{
set { _type = value; }
get { return _type; }
}
}
}



现在从后台获取到类A的查询结果,该结果也是一个IList集合
IList<EB.Common.A>
,现在要给前台返回JSON格式的数据,从网上找了一个通过反射和泛型把IList转换为JSON字符串,转换代码如下:
public static string EntityToJson(IList<T> items)
{
StringBuilder Json = new StringBuilder();
Json.Append("[");
if (items.Count > 0)
{
for (int i = 0; i < items.Count; i++)
{
T obj = Activator.CreateInstance<T>();
Type type = obj.GetType();
PropertyInfo[] pis = type.GetProperties();
Json.Append("{");
for (int j = 0; j < pis.Length; j++)
{
Json.Append("\"" + pis[j].Name.ToString() + "\":\"" + pis[j].GetValue(items[i], null) + "\"");
if (j < pis.Length - 1)
{
Json.Append(",");
}
}
Json.Append("}");
if (i < items.Count - 1)
{
Json.Append(",");
}
}
}
Json.Append("]");
return Json.ToString();
}



如果是正常情况,类的成员变量都是单一类型时(不是Array或List这种),通过下面这种调用方式不会有问题:
//IList<EB.Common.A> rlist = 从数据库获取的数据结果集
string jsonStr = EB.Common.Convertor.IListToJson.JsonHelper<EB.Common.A>.EntityToJson(rlist);



现在就是这种类A的成员变量是个IList集合,在转JSON的时候第二层就有问题:

public static string EntityToJson(IList<T> items)
{
StringBuilder Json = new StringBuilder();
Json.Append("[");
if (items.Count > 0)
{
for (int i = 0; i < items.Count; i++)
{
T obj = Activator.CreateInstance<T>();
Type type = obj.GetType();


PropertyInfo[] pis = type.GetProperties();
Json.Append("{");
for (int j = 0; j < pis.Length; j++)
{
//这里判断类的成员变量是否是IList集合类型
if (pis[j].PropertyType.Name == "IList`1" && pis[j].PropertyType.Namespace == "System.Collections.Generic")
{
//这里如何实现递归调用生成第二层json?
//EntityToJson(IList < T > items);
}
else
{
Json.Append("\"" + pis[j].Name.ToString() + "\":\"" + pis[j].GetValue(items[i], null) + "\"");
if (j < pis.Length - 1)
{
Json.Append(",");
}
}
Json.Append("}");
if (i < items.Count - 1)
{
Json.Append(",");
}
}
}
}
Json.Append("]");
return Json.ToString();
}


请各位高手能够给点思路,或者有没有其他好的方法解决,先谢了!
...全文
245 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
yws871218 2017-04-28
  • 打赏
  • 举报
回复
这是我之前写的一个通用的json转换 只需要传入list直接转换成json格式 与楼主共享
/// <summary>
        /// 转换成json
        /// </summary>
        /// <typeparam name="T">结果数据类型</typeparam>
        /// <param name="t">结果数据</param>
        /// <returns>json数据</returns>
        public static string ConvertToJson<T>(ResultModel<T> t)
        {
            JavaScriptObject ReturnResult = new JavaScriptObject();
            JavaScriptObject ResultMessage = new JavaScriptObject();
            ResultMessage["code"] = t.code;
            ResultMessage["msg"] = t.msg;
            if (t.data != null)
            {
                ResultMessage["data"] = t.data;
            }

            ReturnResult["result"] = ResultMessage;
            return JavaScriptConvert.SerializeObject(ReturnResult);
        }
/// <summary>
    /// 泛型结果集模型
    /// yws
    /// 2016年3月31日13:14:51
    /// </summary>
    [XmlRoot("result")]
    public class ResultBase
    {
        /// <summary>
        /// 结果   
        /// </summary>
        public string code;

        /// <summary>
        /// 提示
        /// </summary>
        public string msg;
    }

    /// <summary>
    /// 泛型结果集模型
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    [XmlRoot("result")]
    public class ResultModel<T> : ResultBase
    {
        /// <summary>
        /// 结果集
        /// </summary>
        public T data;

        /// <summary>
        /// 默认构造函数
        /// </summary>
        public ResultModel()
        { }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="t">内部数据</param>
        public ResultModel(T t)
        {
            data = t;
        }
    }
tangqiaojie 2017-04-26
  • 打赏
  • 举报
回复
做研究也是不错的
tangqiaojie 2017-04-26
  • 打赏
  • 举报
回复
做研究的话也是不多,你可以参考一下人家怎么实现 https://github.com/JamesNK/Newtonsoft.Json
vac_LJ 2017-04-25
  • 打赏
  • 举报
回复
我只能说精神可嘉,我感觉自己实现就是在耗时间,并且性能问题。我没试过,感觉会比官方那东西会慢
tangqiaojie 2017-04-25
  • 打赏
  • 举报
回复
一个人的话很难考虑到所有的数据类型以及所有搭配情况的,还是用官方的方法比较好,这样就很少会出现一些莫名其妙的问题.
tangqiaojie 2017-04-25
  • 打赏
  • 举报
回复
日期方面的转换可以看这个文章:http://www.cnblogs.com/songxingzhu/p/3816309.html,其他自定义转换可以用里面的方案二的方法做些修改就可以了.
sharp_scr 2017-04-24
  • 打赏
  • 举报
回复
代码写的不好,请轻喷 各位大神能否给点思路 或者有其他更好的转JSON的方法都可以说哈~
token不能为空 2017-04-24
  • 打赏
  • 举报
回复
引用 7 楼 sharp_scr 的回复:
主要考虑自己实现能够灵活控制格式或者特殊符号,用序列化比如日期格式等有问题
Newtonsoft作为目前成熟主流的库你能想到的功能他基本都有 你说的日期格式化问题我记得以前看到过,可以实现的 可以搜一下文档学习一下 不过自己研究也对自己有帮助,路过
sharp_scr 2017-04-24
  • 打赏
  • 举报
回复
引用 4 楼 xuzuning 的回复:
嵌套就递归调用呗 有现成的为何不用?
递归的时候 怎么从PropertyInfo信息中得到IList数据呢? 参数里还用的泛型T, 怎么生成这种泛型的参数IList<T>递归呢? 主要考虑自己实现能够灵活控制格式或者特殊符号,用序列化比如日期格式等有问题
tangqiaojie 2017-04-24
  • 打赏
  • 举报
回复
一般用微软开发的或者比较出名的工具比较好,自己转的话, 很多时候很容易有BUG
tangqiaojie 2017-04-24
  • 打赏
  • 举报
回复
还有一个微软自带的可以用:

using System.Web.Script.Serialization;//需要添加引用System.Web.Extensions
使用代码:

           
            A aClass = new A()
            {
                ID = "1",
                Name = "1A",
                Code = "1ACode",
                Detail = new List<B> {
                    new B() { ID= "1", Num=1,Type="1Type" },
                    new B() { ID= "2", Num=2,Type="3Type" },
                },
                DateField = new DateTime(2017, 01, 01, 8, 30, 30, 500) //为了说明另外增加的字段
            };
            //序列化
            JavaScriptSerializer jss = new JavaScriptSerializer();
            string jsonStr = jss.Serialize(aClass);


            //反序列化(动态类型)
            dynamic aDynamic = jss.Deserialize<dynamic>(jsonStr);
            dynamic bList = aDynamic["Detail"];
            string B0ID1 = bList[0]["ID"] + "";//结果:1
            string B0ID2 = aDynamic["Detail"][1]["ID"] + "";//结果:2
            string Name = (string)aDynamic["Name"];//结果:1A
            //注意如果序列化时对象时间没有时区信息,那么范序列化会变成0时区(比北京时间少8小时)
            string DateFieldString = ((DateTime)aDynamic["DateField"]).ToString("yyyy-MM-dd HH:mm:ss.fff");//结果:2017-01-01 00:30:30:5000
            //注意如果序列化时对象时间没有时区信息,如果需要得到当前时区正确时间,需要ToLocalTime
            string DateFieldLocalString = ((DateTime)aDynamic["DateField"]).ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss.fff");////结果:2017-01-01 08:30:30:5000


            //反序列化为对应类型
            A aClass2 = jss.Deserialize<A>(jsonStr);
            IList<B> bList2 = aClass2.Detail;
            string B0ID3 = bList2[0].ID;
            string B0ID4 = aClass2.Detail[1].ID;
            string Name2 = aClass2.Name;
            DateTime DateField2 = aClass2.DateField.ToLocalTime();//结果:当前时间(带时区)

xuzuning 2017-04-24
  • 打赏
  • 举报
回复
嵌套就递归调用呗 有现成的为何不用?
正怒月神 2017-04-24
  • 打赏
  • 举报
回复
2楼正解,Newtonsoft.Json ,现在都用这个
  • 打赏
  • 举报
回复
Newtonsoft.Json 现成的dll用起来

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧