Json序列化和反序列化

序列化:将要传输的对象序列化为二进制的数据流(字符串),叫做序列化。

反序列化:将二进制的数据流(字符串)转化为对象,叫做反序列化。

优点:传输方便,效率高。

Json反序列化原理:读取json文件,生成二进制的数据流(字符串),反序列化成对象。

 

Json文本和实体类对象关系及主要要点:

1."[]"在Json是集合的意思,对应List<RDCInfoModel>集合;

2."{}"在Json是对象的意思,对象RDCInfoModel类;

3.Json键值对,若值是字符串类型,定义string类型;若是整数类型,建议定义Nullable<int>;若是小数类型,建议定义Nullable<double>类型。

   若不加Nullable,Json文件中值为空,实体类中的值就会为0,若加了Nullable,实体类中的值就会为null。

 

 

json文件样本:

Json文件样本对应的实体类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JsonTest
{
    public class RDCConfigModel
    {
        public List<RDCInfoModel> RDCInfo { get; set; }
    }

    public class RDCInfoModel
    {
        public string Name { get; set; }
        public string Client_c { get; set; }
        public string RDC { get; set; }
        public string CusId { get; set; }//月结账号
        public string DotCode { get; set; }//网点代码
        public string Day { get; set; }//要查询多少天前的数据
        public string AllPrint_express_type { get; set; }//快件产品类别,业务类型,目前仅有的1.顺丰次日;5.顺丰次晨
        public string AllPrint_pay_method { get; set; }//付款方式,1:寄方付,2:到付,3:第三方付
        public string AllPrint_need_return_tracking_no { get; set; }//是否要求签回单号:1:要求,其它为不要求
        public string AllPrint_parcel_quantity { get; set; }//包裹数,一个包裹对应一个运单号
        public FixedIssueInfoModel FixedIssueInfo { get; set; }
    }

    public class FixedIssueInfoModel
    {
        public string IsFixedIssueInfo { get; set; }//是否需要固定的寄件人信息,Y or N
        public string ISSUE_PARTY_ADDR { get; set; }//寄件人地址
        public string ISSUE_PARTY_CONTACT { get; set; }//寄件人姓名
        public string ISSUE_PARTY_TEL { get; set; }//寄件人电话
    }
}

反序列化我们需要两个方法,一个是读取Json文件,另一个是反序列化,所有的方法都写在JsonHelper类(using Newtonsoft.Json;)

        /// <summary>
        /// 读取Json文件
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string GetJsonFile(string path)
        {
            StreamReader reader = new StreamReader(path,Encoding.Default);
            string str = reader.ReadToEnd();
            reader.Close();
            reader = null;
            return str;
        }
        /// <summary>
        /// Json反序列化,推荐
        /// </summary>
        /// <typeparam name="T">实体类</typeparam>
        /// <param name="model"></param>
        /// <param name="strJson">json字符串</param>
        /// <returns></returns>
        public static T JsonToModel<T>(T model, string strJson)
        {
            JsonSerializer serizlizer = new JsonSerializer();
            StringReader reader = new StringReader(strJson);
            //以下3种都可行
            //model = (T)serizlizer.Deserialize(new JsonTextReader(reader), typeof(T));
            //model = (T)serizlizer.Deserialize(reader, typeof(T));
            model = serizlizer.Deserialize<T>(new JsonTextReader(reader));
            return model;
        }

        /// <summary>
        /// Json反序列化
        /// </summary>
        /// <typeparam name="T">实体类</typeparam>
        /// <param name="strJson">json字符串</param>
        /// <returns></returns>
        public static List<T> JsonToModel<T>(string strJson)
        {
            JsonSerializer serizlizer = new JsonSerializer();
            StringReader reader = new StringReader(strJson);
            return serizlizer.Deserialize<List<T>>(new JsonTextReader(reader)); ;
        }

最后逻辑

            string RDCPath = Application.StartupPath + "/RDC_Config.json";
            List<RDCConfigModel> RDC_cfg = new List<RDCConfigModel>();
            RDC_cfg = JsonHelper.JsonToModel(RDC_cfg, JsonHelper.GetJsonFile(RDCPath));
            foreach (var item in RDC_cfg[0].RDCInfo)
            {
                Console.WriteLine(item.Name);
            }

因为Json样本文件开头带有  "RDCInfo":

故在遍历对象的时候,索引值是固定在0.如 foreach (var item in RDC_cfg[0].RDCInfo)

如果Json样本文件开头不带有  "RDCInfo":

如图:

则最后逻辑应该这样:

            string RDCPath2 = Application.StartupPath + "/RDC_Config - 副本.json";
            List<RDCInfoModel> RDC_cfg2 = new List<RDCInfoModel>();
            RDC_cfg2 = JsonHelper.JsonToModel(RDC_cfg2, JsonHelper.GetJsonFile(RDCPath2));
            foreach (var item in RDC_cfg2)
            {
                Console.WriteLine(item.Name);
            }

值得区分的是 List<RDCInfoModel> RDC_cfg2 = new List<RDCInfoModel>(); 和  foreach (var item in RDC_cfg2)

 

 

Json序列化原理:将对象转成二进制的数据流(字符串),再写入到json文件

 ---上述已经将Json文件反序列化成对象了,下面就可以通过这些对象序列化成二进制的数据流(字符串),再写入到json文件,等于回到起点。

首先需要两个方法,一个是序列化方法,另一个是将字符串写入Json文件。

        /// <summary>
        /// Json序列化
        /// </summary>
        /// <returns></returns>
        public static string GetJsonString<T>(T o)
        {
            JsonSerializer serizlizer = new JsonSerializer();
            StringWriter sw = new StringWriter();
            serizlizer.Serialize(new JsonTextWriter(sw), o);
            return sw.GetStringBuilder().ToString();
        }

        /// <summary>
        /// 生成文件
        /// </summary>
        /// <param name="path"></param>
        /// <param name="str"></param>
        public static void WriteFile(string path, string str)
        {
            FileStream fs = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
            StreamWriter sw = new StreamWriter(fs);
            sw.WriteLine(str);
            sw.Flush();
            sw.Close();
            sw.Dispose();
            fs.Close();
            fs.Dispose();
        }

最后逻辑

            string str1 = JsonHelper.GetJsonString(RDC_cfg2);
            JsonHelper.WriteFile(@"F:\TestFile\test1.json", str1);

            string str2 = JsonHelper.GetJsonString(RDC_cfg);           
            JsonHelper.WriteFile(@"F:\TestFile\test2.json", str2);

生成的两个Json文件和上面的一样。

 

posted @ 2017-02-03 14:16  花生打代码会头痛  阅读(1321)  评论(0)    收藏  举报