消息关闭
    暂无新消息!

关于解析JSON的问题

问题作者 : 风云2017-06-18发布
比如我有一段JSON有5个字段,订单,联系人,联系地址,联系电话,商品,其中商品字段是个集合,集合中一共有3个元素,也就是说同一个订单有3件商品,那么我要解析成3条记录,这3条记录分别都要有订单,联系人,联系地址,联系电话,商品信息,之前都是一个订单一件商品,这个容易解决,现在出现这种情况,我不知道该这么解析了。

7个回答

︿ 3
说到解析,其实跟数据结构基本知识有关。虽然你可能在某个程序中并不真的去把 json 字符串解析为强类型的自定义数据结构,而是解析为灵活结构的 JObject、JArray、ExpandoObject、List<ExpandoObject> 等等,但是假设你“写不出来数据结构”,或者数据结构中有静态嵌套结构,那么这就会有好多设计问题。

所以你的问题,不管你是否最终要解析强类型的面向业务的自定义数据结构,只要有理解上的问题,都应该先自己写出来一个自定义的数据结构作为分析的基础。
︿ 2
{
    "订单": "170600001",
    "联系人": "张三",
    "联系地址": "中国淘宝村",
    "联系电话": "8888-88888888",
    "商品信息": [
        "情趣内衣",
        "寒光剑",
        "偃月刀"
    ]
}
解析JSON对象,商品信息作为数组。
︿ 2
对于设计一个 class 结构,假设一个人“会”

public class A
{
    public B prod;
    ....
}
这样的设计而不“会”
public class A
{
    public List<B> prods;
    .....
}
这样的设计,我们其实应该好好分析一下背后的原因。
︿ 1
这就好像是你给别人介绍自己,既要说到你的细节又要有整体架构,又要言简意赅。

你心里应该对于“订单”这个概念有一个直观的图形,那么你就知道其中的“订单头、明细、明细项目、付款、付款方式、运输、运输明细、签收”等等可以有多种形式,而哪一种形式更加适合领域模型的本质(而不是你自己觉得简单方便)。

你说的“那么我要解析成3条记录,这3条记录分别都要有订单,联系人,联系地址,联系电话,商品信息”这个话,其实一般来说会第一时间就被排除掉。你还是在千方百计地套用你的“之前都是一个订单一件商品”这种概念,产生了多余的所谓“解析”要求。
︿ 0
还有一种比较常见的:父子表——单头表:订单、联系人、联系地址、联系电话,单身表:订单、序号、商品。
反序列化解析后ADO.NET 直接存储,反序列化的类很多,参考下面的。
--JSON 实例--
{
    "dt": {
        "订单": "170600001",
        "联系人": "张三",
        "联系地址": "中国淘宝村",
        "联系电话": "8888-88888888"
    },
    "ds": [
        {
            "序号": "0010",
            "商品": "情趣内衣"
        },
        {
            "序号": "0020",
            "商品": "寒光剑"
        },
        {
            "序号": "0030",
            "商品": "偃月刀"
        }
    ]
}



using Newtonsoft.Json;

    public class JSONhelper
    {
        /// <summary>
        /// 将对象序列化为JSON格式
        /// </summary>
        /// <param name="o">对象</param>
        /// <returns>json字符串</returns>
        public static string SerializeObject(object o)
        {
            string json = JsonConvert.SerializeObject(o);
            return json;
        }

        /// <summary>
        /// 解析JSON字符串生成对象实体
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="json">json字符串(eg.{"ID":"112","Name":"石子儿"})</param>
        /// <returns>对象实体</returns>
        public static T DeserializeJsonToObject<T>(string json) where T : class
        {
            JsonSerializer serializer = new JsonSerializer();
            StringReader sr = new StringReader(json);
            object o = serializer.Deserialize(new JsonTextReader(sr), typeof(T));
            T t = o as T;
            return t;
        }

        /// <summary>
        /// 解析JSON数组生成对象实体集合
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="json">json数组字符串(eg.[{"ID":"112","Name":"石子儿"}])</param>
        /// <returns>对象实体集合</returns>
        public static List<T> DeserializeJsonToList<T>(string json) where T : class
        {
            JsonSerializer serializer = new JsonSerializer();
            StringReader sr = new StringReader(json);
            object o = serializer.Deserialize(new JsonTextReader(sr), typeof(List<T>));
            List<T> list = o as List<T>;
            return list;
        }

        /// <summary>
        /// 反序列化JSON到给定的匿名对象.
        /// </summary>
        /// <typeparam name="T">匿名对象类型</typeparam>
        /// <param name="json">json字符串</param>
        /// <param name="anonymousTypeObject">匿名对象</param>
        /// <returns>匿名对象</returns>
        public static T DeserializeAnonymousType<T>(string json, T anonymousTypeObject)
        {
            T t = JsonConvert.DeserializeAnonymousType(json, anonymousTypeObject);
            return t;
        }


        /// <summary>
        /// DataTable 转泛型list
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public class ModelConvertHelper<T> where T : new()  // 此处一定要加上new()
        {

            public static IList<T> ConvertToModel(DataTable dt)
            {

                IList<T> ts = new List<T>();// 定义集合
                Type type = typeof(T); // 获得此模型的类型
                string tempName = "";
                foreach (DataRow dr in dt.Rows)
                {
                    T t = new T();
                    PropertyInfo[] propertys = t.GetType().GetProperties();// 获得此模型的公共属性
                    foreach (PropertyInfo pi in propertys)
                    {
                        tempName = pi.Name;
                        if (dt.Columns.Contains(tempName))
                        {
                            if (!pi.CanWrite) continue;
                            object value = dr[tempName];
                            if (value != DBNull.Value)
                                pi.SetValue(t, value, null);
                        }
                    }
                    ts.Add(t);
                }
                return ts;
            }
        }
}