最近開發中用到較多的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的相關內容.