Newtonsoft.Json序列化系列之一

最近開發中用到較多的json序列的業務實現,抽空學習了一下Newtonsoft.Json的相關內容,直接上演示代碼,本篇關注點在json的序列化與反序列化,以下代碼相信能滿足90%以上的需求場景:

using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {

            //Json.NET簡介,dll版本:6.0.4.17603
            //Flexible JSON serializer for converting between .NET objects and JSON
            //LINQ to JSON for manually reading and writing JSON
            //High performance: faster than.NET's built-in JSON serializers
            //Write indented, easy - to - read JSON
            //Convert JSON to and from XML
            //Supports .NET Standard 2.0, .NET 2, .NET 3.5, .NET 4, .NET 4.5, Silverlight, Windows Phone and Windows 8 Store
            //常用類:JsonSerializer,JsonConvert,JsonSerializerSettings 
            //JsonConvert用於簡單的序列化與反序列化,通過JsonConvert.SerializeObject()及 JsonConvert.DeserializeObject(),是對JsonSerializer進行的易用封裝,
            //JsonSerializer 用於複雜的場景,它可以直接序列化一個實體對象到流中
            //JsonSerializerSettings用於在序列化時的自定義設置
            //自帶.net可序列化與反序列化:IList, IEnumerable, IList<T>, Array,IDictionary, IDictionary<TKey, TValue>,Untyped Objects,ISerializable(e.g. DataTable),LINQ to JSON(e.g. JObject and JArray)
            //序列化時會自動忽略其他屬性
            //其他:Json.net還具備其他特性:序列化回調,局部序列化, 條件序列化(滿足一定條件的字段纔會序列化),序列化屬性(用於設定序列化規則)等,
            //例如在opt-out 模式下.可以通過給字段添加JsonIgnoreAttribute使它不被序列化
            //官網https://www.newtonsoft.com/json/help/html/Introduction.htm
            #region 序列化->.net對象轉換爲json字符串       
            #region 序列化實體對象
            Account account = new Account
            {
                Email = "[email protected]",
                Active = true,
                CreatedDate = new DateTime(2013, 1, 20, 0, 0, 0, DateTimeKind.Utc),
                Roles = new List<string> { "User", "Admin" }
            };
            // Formatting.Indented設置json縮進
            string json = JsonConvert.SerializeObject(account, Formatting.Indented);
            // {
            //   "Email": "[email protected]",
            //   "Active": true,
            //   "CreatedDate": "2013-01-20T00:00:00Z",
            //   "Roles": [
            //     "User",
            //     "Admin"
            //   ]
            // } 
            #endregion
            #region 序列化一個集合
            List<string> videogames = new List<string>
            {
            "Starcraft",
            "Halo",
            "Legend of Zelda"
            };
            json = JsonConvert.SerializeObject(videogames);
            // ["Starcraft","Halo","Legend of Zelda"]
            #endregion
            #region 序列化DataSet,DataTable
            DataSet dataSet = new DataSet("dataSet");
            dataSet.Namespace = "NetFrameWork";
            DataTable table = new DataTable();
            DataColumn idColumn = new DataColumn("id", typeof(int));
            idColumn.AutoIncrement = true;

            DataColumn itemColumn = new DataColumn("item");
            table.Columns.Add(idColumn);
            table.Columns.Add(itemColumn);
            dataSet.Tables.Add(table);

            for (int i = 0; i < 2; i++)
            {
                DataRow newRow = table.NewRow();
                newRow["item"] = "item " + i;
                table.Rows.Add(newRow);
            }
            dataSet.AcceptChanges();
            json = JsonConvert.SerializeObject(dataSet, Formatting.Indented);//也可以直接序列化table
            // {
            //   "Table1": [
            //     {
            //       "id": 0,
            //       "item": "item 0"
            //     },
            //     {
            //       "id": 1,
            //       "item": "item 1"
            //     }
            //   ]
            // }

            #endregion
            #region 條件序列化
            Employee joe = new Employee();
            joe.Name = "Joe Employee";
            Employee mike = new Employee();
            mike.Name = "Mike Manager";
            joe.Manager = mike;
            // mike is his own manager
            // ShouldSerialize will skip this property
            mike.Manager = mike;
            json = JsonConvert.SerializeObject(new[] { joe, mike }, Formatting.Indented);
            // [
            //   {
            //     "Name": "Joe Employee",
            //     "Manager": {
            //       "Name": "Mike Manager"
            //     }
            //   },
            //   {
            //     "Name": "Mike Manager"
            //   }
            // ]
            #endregion
            #endregion
            #region 反序列化->json字符串轉換爲.net對象
            #region 反序列化實體對象
            json = @"{
          'Email': '[email protected]',
          'Active': true,
          'CreatedDate': '2013-01-20T00:00:00Z',
          'Roles': [
            'User',
            'Admin'
          ]
        }";
            account = JsonConvert.DeserializeObject<Account>(json);

            #endregion
            #region 反序列化集合
            json = @"['Starcraft','Halo','Legend of Zelda']";
            videogames = JsonConvert.DeserializeObject<List<string>>(json);
            #endregion
            #region 反序列化匿名類
            var definition = new { Name = "" };
            string json1 = @"{'Name':'James'}";
            var customer1 = JsonConvert.DeserializeAnonymousType(json1, definition);
            Console.WriteLine(customer1.Name);
            // James
            string json2 = @"{'Name':'Mike'}";
            var customer2 = JsonConvert.DeserializeAnonymousType(json2, definition);
            Console.WriteLine(customer2.Name);
            // Mike
            #endregion
            #region 反序列化DataSet,DataTable
            json = @"{
              'Table1': [
                {
                  'id': 0,
                  'item': 'item 0'
                },
                {
                  'id': 1,
                  'item': 'item 1'
                }
              ]
            }";
            var json_1 = @"
              [
                {
                  'id': 0,
                  'item': 'item 0'
                },
                {
                  'id': 1,
                  'item': 'item 1'
                }
              ]
            ";
            dataSet = JsonConvert.DeserializeObject<DataSet>(json);
            DataTable dt = JsonConvert.DeserializeObject<DataTable>(json_1);
            DataTable dataTable = dataSet.Tables["Table1"];

            Console.WriteLine(dataTable.Rows.Count);
            // 2

            foreach (DataRow row in dataTable.Rows)
            {
                Console.WriteLine(row["id"] + " - " + row["item"]);
            }
            // 0 - item 0
            // 1 - item 1
            #endregion
            #region 從文件中反序列化
            // read file into a string and deserialize JSON to a type
            Movie movie1 = JsonConvert.DeserializeObject<Movie>(File.ReadAllText(@"c:\movie.json"));
            // deserialize JSON directly from a file
            using (StreamReader file = File.OpenText(@"c:\movie.json"))
            {
                JsonSerializer serializer = new JsonSerializer();
                Movie movie2 = (Movie)serializer.Deserialize(file, typeof(Movie));
            }
            #endregion
            #endregion
            #region JsonSerializerSettings的使用
            #region 成員丟失時,序列與反序列都適用,適合局部序列化場景
            json = @"{
              'FullName': 'Dan Deleted',
              'Deleted': true,
              'DeletedDate': '2013-01-20T00:00:00'
            }";
            account = JsonConvert.DeserializeObject<Account>(json, new JsonSerializerSettings
            {
                //MissingMemberHandling = MissingMemberHandling.Error 將會拋出異常
                MissingMemberHandling = MissingMemberHandling.Ignore
            }); ;
            #endregion
            #region 空值設置
            Person person = new Person
            {
                Name = "Nigal Newborn",
                Age = 1
            };

            string jsonIncludeNullValues = JsonConvert.SerializeObject(person, Formatting.Indented);

            Console.WriteLine(jsonIncludeNullValues);
            // {
            //   "Name": "Nigal Newborn",
            //   "Age": 1,
            //   "Partner": null,
            //   "Salary": null
            // }

            string jsonIgnoreNullValues = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Ignore
            });

            Console.WriteLine(jsonIgnoreNullValues);
            // {
            //   "Name": "Nigal Newborn",
            //   "Age": 1
            // }
            #endregion
            #region 日期格式設置
            DateTime mayanEndOfTheWorld = new DateTime(2012, 12, 21);
            string jsonIsoDate = JsonConvert.SerializeObject(mayanEndOfTheWorld);
            Console.WriteLine(jsonIsoDate);
            // "2012-12-21T00:00:00"
            string jsonMsDate = JsonConvert.SerializeObject(mayanEndOfTheWorld, new JsonSerializerSettings
            {
                DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
            });
            Console.WriteLine(jsonMsDate);
            // "\/Date(1356044400000+0100)\/"
            #endregion
            #region json與DateTime的正反序列,省去冗長的轉換
            //正序列
            IList<DateTime> dateList = new List<DateTime>
            {
                new DateTime(2009, 12, 7, 23, 10, 0, DateTimeKind.Utc),
                new DateTime(2010, 1, 1, 9, 0, 0, DateTimeKind.Utc),
                new DateTime(2010, 2, 10, 10, 0, 0, DateTimeKind.Utc)
            };
             json = JsonConvert.SerializeObject(dateList, new JsonSerializerSettings
            {
                DateFormatString = "d MMMM, yyyy",
                Formatting = Formatting.Indented
            });
            Console.WriteLine(json);
            // [
            //   "7 December, 2009",
            //   "1 January, 2010",
            //   "10 February, 2010"
            // ]

            //反序列
              json = @"[
              '7 December, 2009',
              '1 January, 2010',
              '10 February, 2010'
            ]";

            dateList = JsonConvert.DeserializeObject<IList<DateTime>>(json, new JsonSerializerSettings
            {
                DateFormatString = "d MMMM, yyyy"
            });

            foreach (DateTime dateTime in dateList)
            {
                Console.WriteLine(dateTime.ToLongDateString());
            }
            // Monday, 07 December 2009
            // Friday, 01 January 2010
            // Wednesday, 10 February 2010
            IsoDateTimeConverter timeFormat = new IsoDateTimeConverter();
            timeFormat.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
            JsonConvert.SerializeObject(null, timeFormat, new DataTableConverter());
            #endregion
            #endregion
            //下期分享LINQ to JSON程序集相關內容
        }

    }

    public class Account
    {
        public string Email { get; set; }
        public bool Active { get; set; }
        public DateTime CreatedDate { get; set; }
        public IList<string> Roles { get; set; }
    }

    public class Account1
    {
        public string FullName { get; set; }
        public bool Deleted { get; set; }
    }

    public class Employee
    {
        public string Name { get; set; }
        public Employee Manager { get; set; }

        //需要對哪個屬性則實現一個ShouldSerialize+屬性名的方法,根據返回的bool值確定是否序列化.這樣可以很方便的序列化我們想要的字段
        public bool ShouldSerializeManager()
        {
            // don't serialize the Manager property if an employee is their own manager
            return (Manager != this);
        }
    }

    public class Movie
    {
        public string Name { get; set; }
        public int Year { get; set; }
    }

    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public Person Partner { get; set; }
        public decimal? Salary { get; set; }
    }
}

下次學習LINQ to JSON的相關內容.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章