1. 程式人生 > >json.net使用說明二

json.net使用說明二

枚舉類型 truct 保持 轉換 pos target s函數 rst 對象

1、使用JSON.NET序列化對象
public class Account
{
    public string Email { get; set; }
    public bool Active { get; set; }
    public DateTime CreatedDate { get; set; }
    public IList<string> Roles { get; set; }
}
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" } }; string json = JsonConvert.SerializeObject(account, Formatting.Indented); Console.WriteLine(json); { "Email": "[email protected]", "Active": true, "CreatedDate": "2013-01-20T00:00:00Z", "Roles"
: [ "User", "Admin" ] } 2、使用JSON.NET序列化List集合 List<string> videogames = new List<string> { "零度", "分享", "編程之美" }; string json = JsonConvert.SerializeObject(videogames); Console.WriteLine(json); ["零度","分享","編程之美"] 3、使用JSON.NET序列化dictionary字典 var points = new Dictionary<string, int
> { { "James", 9001 }, { "Jo", 3474 }, { "Jess", 11926 } }; string json = JsonConvert.SerializeObject(points, Formatting.Indented); Console.WriteLine(json); { "James": 9001, "Jo": 3474, "Jess": 11926 } 4、將序列化結果保存到指定的文件 public class Movie { public string Name { get; set; } public int Year { get; set; } } Movie movie = new Movie { Name = "Bad Boys", Year = 1995 }; using (StreamWriter file = File.CreateText(@"e:\movie.json")) { JsonSerializer serializer = new JsonSerializer(); serializer.Serialize(file, movie); } 5、基於枚舉類型的JsonConverters轉換器 public enum StringComparison { CurrentCulture = 0, CurrentCultureIgnoreCase = 1, InvariantCulture = 2 } List<StringComparison> stringComparisons = new List<StringComparison> { StringComparison.CurrentCulture, StringComparison.InvariantCulture }; string jsonWithoutConverter = JsonConvert.SerializeObject(stringComparisons); Console.WriteLine(jsonWithoutConverter); [0,2] string jsonWithConverter = JsonConvert.SerializeObject(stringComparisons, new StringEnumConverter()); Console.WriteLine(jsonWithConverter); ["CurrentCulture","InvariantCulture"] var result = JsonConvert.DeserializeObject<List<StringComparison>>(jsonWithConverter, new StringEnumConverter()); Console.WriteLine(string.Join(", ", result.Select(c => c.ToString()))); CurrentCulture, InvariantCulture 6、通過JRaw將JS函數序列化到JSON中 public class JavaScriptSettings { public JRaw OnLoadFunction { get; set; } public JRaw OnUnloadFunction { get; set; } } JavaScriptSettings settings = new JavaScriptSettings { OnLoadFunction = new JRaw("OnLoad"), OnUnloadFunction = new JRaw("function(e) { alert(e); }") }; string json = JsonConvert.SerializeObject(settings, Formatting.Indented); Console.WriteLine(json); { "OnLoadFunction": OnLoad, "OnUnloadFunction": function(e) { alert(e); } } 7、使用JSON.NET反序列化對象 public class Account { public string Email { get; set; } public bool Active { get; set; } public DateTime CreatedDate { get; set; } public IList<string> Roles { get; set; } } string json = @"{ ‘Email‘: ‘[email protected]‘, ‘Active‘: true, ‘CreatedDate‘: ‘2013-01-20T00:00:00Z‘, ‘Roles‘: [ ‘User‘, ‘Admin‘ ] }"; Account account = JsonConvert.DeserializeObject<Account>(json); Console.WriteLine(account.Email); [email protected] 8、使用JSON.NET反序列化List集合 string json = @"[‘Starcraft‘,‘Halo‘,‘Legend of Zelda‘]"; List<string> videogames = JsonConvert.DeserializeObject<List<string>>(json); Console.WriteLine(string.Join(", ", videogames)); Starcraft, Halo, Legend of Zelda 9、使用JSON.NET反序列化dictionary字典 string json = @"{‘href‘: ‘www.xcode.me‘,‘target‘: ‘_blank‘}"; var htmlAttributes = JsonConvert.DeserializeObject<Dictionary<string, string>>(json); Console.WriteLine(htmlAttributes["href"]); www.xcode.me 10、序列化var匿名類型 有時候,我們並不需要先定義一個類,然後new一個對象後再進行序列化,JSON.NET支持匿名類型的序列化和反序列化。 var definition = new { Name = "零度編程", Site = "www.xcode.me" }; var json = JsonConvert.SerializeObject(definition); Console.WriteLine(json); { "Name": "零度編程", "Site": "www.xcode.me" } var definition = new { Name = "", Site = "" }; string json = @"{‘Name‘:‘零度編程‘,‘Site‘:‘www.xcode.me‘}"; var webSite = JsonConvert.DeserializeAnonymousType(json, definition); Console.WriteLine(webSite.Name); 零度編程 11、用新JSON字符串填充指定對象的屬性值 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"} }; string json = @"{‘Active‘: false, ‘Roles‘: [‘Expired‘]}"; JsonConvert.PopulateObject(json, account); Console.WriteLine(account.Active); false 上面的示例中,account對象的Active值首次設置為true,可通過PopulateObject方法通過json字符串重新填充Active屬性和Roles屬性。 12、使用JSON.NET反序列化時可指定構造函數 首先我們定義如下的類型,我們希望JSON.NET反序列化對象時使用第2個構造函數,我們將第一個默認構造函數屏蔽,標記為私有private修飾符。第2個構造函數需要指定一個website對象作為參數,如果提供的參數為null則拋出異常: public class Website { public string Url { get; set; } private Website() { } public Website(Website website) { if (website == null) throw new ArgumentNullException("website"); Url = website.Url; } } 現在使用一般的方式反序列化一個JSON字符串。 string json = @"{‘Url‘:‘http://www.xcode.me‘}"; try { JsonConvert.DeserializeObject<Website>(json); } catch (Exception ex) { Console.WriteLine(ex); } Value cannot be null.Parameter name: website 我們發現該序列化方法拋出了異常,並沒有按照我們預想的方式進行反序列化,JSON.NET提供如下的方式指定公有構造函數。 Website website = JsonConvert.DeserializeObject<Website>(json, new JsonSerializerSettings { ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor }); Console.WriteLine(website.Url); http://www.xcode.me 另外,JSON.NET提供了指定任何構造函數的JsonConstructorAttribute特性,只需要在構造函數上標記,即可指定構造函數。 public class User { public string UserName { get; private set; } public bool Enabled { get; private set; } public User() { } [JsonConstructor] public User(string userName, bool enabled) { UserName = userName; Enabled = enabled; } } string json = @"{""UserName"": ""www.xcode.me"",""Enabled"": true}"; User user = JsonConvert.DeserializeObject<User>(json); Console.WriteLine(user.UserName); www.xcode.me 13、當對象的屬性為默認值(0或null)時不序列化該屬性 public class Person { public string Name { get; set; } public int Age { get; set; } public Person Partner { get; set; } public decimal? Salary { get; set; } } Person person = new Person(); string jsonIncludeDefaultValues = JsonConvert.SerializeObject(person, Formatting.Indented); Console.WriteLine(jsonIncludeDefaultValues); { "Name": null, "Age": 0, "Partner": null, "Salary": null } string json = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore }); Console.WriteLine(json); {} 14、反序列化時JSON屬性與對象屬性的數量必須一致 默認情況下,JSON.NET反序列化並不要求JSON屬性的數量與對象屬性的數量相等,也就是始終保持有則序列化,無則不序列化的原則,不會拋出異常。但是,我們的需求並非這樣,我們希望屬性數量不等或者未提供值時,拋出異常,而不是正常反序列化,可以這樣。 public class Account { public string FullName { get; set; } public bool Deleted { get; set; } } string json = @"{ ‘FullName‘: ‘Dan Deleted‘, ‘Deleted‘: true, ‘DeletedDate‘: ‘2013-01-20T00:00:00‘ }"; try { JsonConvert.DeserializeObject<Account>(json, new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Error }); } catch (JsonSerializationException ex) { Console.WriteLine(ex.Message); } Could not find member DeletedDate on object of type Account. Path DeletedDate, line 4, position 23. 這樣,當未全部指定對象的屬性時,就會拋出異常,而不是部分屬性序列化。 15、JSON.NET中忽略null值得處理器 public class Person { public string Name { get; set; } public int Age { get; set; } public Person Partner { get; set; } public decimal? Salary { get; set; } } 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 json = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); Console.WriteLine(json); { "Name": "Nigal Newborn", "Age": 1 } 在上面的示例中,默認情況下JSON.NET會將對象的null屬性值序列化為JSON中null值。當對象屬性值為null時,可忽略序列化,只需要指定NullValueHandling即可,另外有一種場景是,當對象屬性值為null時,需要替換為空字符串雙引號,如何替換,請點擊這裏參閱零度的文章。 16、JSON.NET中循環引用的處理方法 有的對象具有循環引用,對象的屬性是對象本身,這會導致JSON.NET進入無限死循環,我們需要指定ReferenceLoopHandling打破這種循環引用。 public class Employee { public string Name { get; set; } public Employee Manager { get; set; } } Employee joe = new Employee { Name = "Joe User" }; Employee mike = new Employee { Name = "Mike Manager" }; joe.Manager = mike; mike.Manager = mike; string json = JsonConvert.SerializeObject(joe, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); Console.WriteLine(json); { "Name": "Joe User", "Manager": { "Name": "Mike Manager" } } 17、通過ContractResolver指定屬性名首字母小寫 通常,在.NET中屬性采用PascalCase規則(首字母大寫),在JavaScript中屬性名使用CamelCase規則(首字母小寫),我們希望序列化後的JSON字符串符合CamelCase規則,JSON.NET提供的ContractResolver可以設置屬性名小寫序列化,更靈活的設置請點擊這裏參閱零度的文章。 public class Person { public string FirstName { get; set; } public string LastName { get; set; } public string FullName { get { return FirstName + " " + LastName; } } } Person person = new Person { FirstName = "Sarah", LastName = "Security" }; string json = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }); Console.WriteLine(json); { "firstName": "Sarah", "lastName": "Security", "fullName": "Sarah Security" } 18、JSON.NET中通過特性序列化枚舉類型 public enum UserStatus { NotConfirmed, Active, Deleted } public class User { public string UserName { get; set; } [JsonConverter(typeof(StringEnumConverter))] public UserStatus Status { get; set; } } 默認情況下JSON.NET針對枚舉類型輸出對應的INT值,如果需要輸出具有語義的字符串,可指定JsonConverter的值為StringEnumConverter類型。 User user = new User { UserName = @"零度編程", Status = UserStatus.Deleted }; string json = JsonConvert.SerializeObject(user, Formatting.Indented); Console.WriteLine(json); { "UserName": "零度編程", "Status": "Deleted" } 19、指定需要序列化的屬性 通過JsonProperty指定哪些字段應該被序列化,需要序列化則標記,不需要序列化則取消標記。 [JsonObject(MemberSerialization.OptIn)] public class File { //Id不需要序列化 public Guid Id { get; set; } [JsonProperty] public string Name { get; set; } [JsonProperty] public int Size { get; set; } } File file = new File { Id = Guid.NewGuid(), Name = "xcode.pdf", Size = 50 * 1024 }; string json = JsonConvert.SerializeObject(file, Formatting.Indented); Console.WriteLine(json); { "Name": "xcode.pdf", "Size": 51200 } 20、序列化對象時指定屬性名 序列化對象時,可標記屬性的JsonProperty特性,並指定需要序列化為JSON時應有的屬性名。 public class Videogame { [JsonProperty("name")] public string Name { get; set; } [JsonProperty("release_date")] public DateTime ReleaseDate { get; set; } } Videogame starcraft = new Videogame { Name = "Starcraft", ReleaseDate = new DateTime(1998, 1, 1) }; string json = JsonConvert.SerializeObject(starcraft, Formatting.Indented); Console.WriteLine(json); { "name": "Starcraft", "release_date": "1998-01-01T00:00:00" } 21、序列化時指定屬性在JSON中的順序 public class Person { [JsonProperty(Order = 2)] public string FirstName { get; set; } [JsonProperty(Order = 1)] public string LastName { get; set; } } Person person = new Person { FirstName = "零度", LastName = "編程" }; string json = JsonConvert.SerializeObject(person, Formatting.Indented); Console.WriteLine(json); { "LastName": "編程", "FirstName": "零度" } 22、反序列化指定屬性是否必須有值必須不為null 在反序列化一個JSON時,可通過JsonProperty特性的Required指定反序列化行為,當反序列化行為與指定的行為不匹配時,JSON.NET將拋出異常,Required是枚舉,Required.Always表示屬性必須有值切不能為null,Required.AllowNull表示屬性必須有值,但允許為null值。 public class Videogame { [JsonProperty(Required = Required.Always)] public string Name { get; set; } [JsonProperty(Required = Required.AllowNull)] public DateTime? ReleaseDate { get; set; } } string json = @"{ ‘Name‘: ‘Starcraft III‘, ‘ReleaseDate‘: null }"; Videogame starcraft = JsonConvert.DeserializeObject<Videogame>(json); Console.WriteLine(starcraft.Name); Starcraft III 23、通過特性指定null值忽略序列化 public class Vessel { public string Name { get; set; } public string Class { get; set; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public DateTime? LaunchDate { get; set; } } Vessel vessel = new Vessel { Name = "Red October", Class = "Typhoon" }; string json = JsonConvert.SerializeObject(vessel, Formatting.Indented); Console.WriteLine(json); { "Name": "Red October", "Class": "Typhoon" } 24、忽略不需要序列化的屬性 並不是對象所有屬性都要參與序列化,我們可以使用JsonIgnore特性排除不需要序列化的屬性,下面示例中的PasswordHash將被忽略。 public class Account { public string FullName { get; set; } public string EmailAddress { get; set; } [JsonIgnore] public string PasswordHash { get; set; } } Account account = new Account { FullName = "admin", EmailAddress = "[email protected]", PasswordHash = "VHdlZXQgJ1FASmFtZXNOSw==" }; string json = JsonConvert.SerializeObject(account); Console.WriteLine(json); {"FullName":"admin","EmailAddress":[email protected]} 25、通過特性指定屬性的默認序列化值 當屬性沒有賦值時,默認值一般是null或者0,我們可通過DefaultValue特性改變默認值,可用指定的字符替換,而不是輸出null。 public class Customer { public string FirstName { get; set; } [DefaultValue("")] public string LastName { get; set; } } {"FirstName":null,"LastName":""} 26、序列化或反序列化時指定日期時間格式 JSON.NET中提供一個名為JsonSerializerSettings的設置對象,可通過此對象設置很多序列化和反序列化的行為,如果要設置JSON.NET序列化輸出的日期時間格式,只需要指定格式化字符串即可。默認序列化行為,日期時間格式如下: public class Customer { public string FirstName { get; set; } public string LastName { get; set; } public DateTime CreateDate { get; set; } } var custom = new Customer { FirstName = "零度", LastName = "編程", CreateDate = DateTime.Now }; string json = JsonConvert.SerializeObject(custom, Formatting.Indented); Console.WriteLine(json); { "FirstName": "零度", "LastName": "編程", "CreateDate": "2015-08-24T17:19:39.0227502+08:00" } 通過JsonSerializerSettings的DateFormatString屬性指定日期時間格式: JsonSerializerSettings settings = new JsonSerializerSettings(); settings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; settings.Formatting = Formatting.Indented; string json = JsonConvert.SerializeObject(custom, settings); Console.WriteLine(json); { "FirstName": "零度", "LastName": "編程", "CreateDate": "2015-08-24 17:23:56" } 27、JSON字符串格式化 默認情況下通過JsonConvert.SerializeObject(object value)序列化後的JSON是壓縮格式,為了便於閱讀,通常需要將JSON字符串格式化處理。 var value = new Customer { FirstName = "零度", LastName = "編程"}; string json = JsonConvert.SerializeObject(value); Console.WriteLine(json); {"FirstName":"零度","LastName":"編程"} 以上為指定格式化,將輸出壓縮版JSON字符串,可通過Formatting.Indented指定格式化輸出。 string json = JsonConvert.SerializeObject(value, Formatting.Indented); Console.WriteLine(json); { "FirstName": "零度", "LastName": "編程" } 也可以指定JsonSerializerSettings對象的Formatting值為Formatting.Indented進行格式化,與上面的結果等效。 JsonSerializerSettings settings = new JsonSerializerSettings(); settings.Formatting = Formatting.Indented; string json = JsonConvert.SerializeObject(value, settings); Console.WriteLine(json);

json.net使用說明二