序列化和反序列化JSON
JsonConvert
对于想要与 JSON 字符串相互转换的简单场景, JsonConvert 上的SerializeObject ()和 DeserializeObject () 方法在 JsonSerializer 上提供了易于使用的包装器。
下面代码使用序列化与反序列化:
1 class Product 2 { 3 [JsonIgnore] 4 public string Name { get; set; } 5 public DateTime ExpiryDate { get; set; } 6 public int Price { get; set; } 7 public string[] Sizes { get; set; } 8 9 } 10 Product product = new() 11 { 12 Name = "Davis", 13 ExpiryDate = DateTime.Now, 14 Price = 158, 15 Sizes = new[] {"small","medium","large"} 16 }; 17 string output = JsonConvert.SerializeObject(product); 18 Product product1 = JsonConvert.DeserializeObject<Product>(output);
注意:因为Product类中的Name特性为[JsonIgnore]所以忽略了此属性
output结果如图:
product1结果如图:
JsonSerializer
为了更好地控制对象的序列化方式,可以直接使用JsonSerializer 。JsonSerializer 能够通过JsonTextReader 和JsonTextWriter直接读取 JSON 文本并将其写入流。还可以使用其他类型的 JsonWriter,例如 JTokenReader / JTokenWriter将对象与 LINQ 对象相互转换为 JSON 对象,或者 BsonReader / BsonWriter将对象与 BSON 相互转换。
使用JsonSeriallizer将Json序列化为流,代码如下:
1 Product product = new Product(); 2 product.ExpiryDate = new DateTime(2008, 12, 28); 3 4 JsonSerializer serializer = new JsonSerializer(); 5 serializer.Converters.Add(new JavaScriptDateTimeConverter()); 6 serializer.NullValueHandling = NullValueHandling.Ignore; 7 8 using (StreamWriter sw = new StreamWriter(@"c:\json.txt")) 9 using (JsonWriter writer = new JsonTextWriter(sw)) 10 { 11 serializer.Serialize(writer, product); 12 // {"ExpiryDate":new Date(1230375600000),"Price":0} 13 }
序列化指南
在较高级别上,Json.NET 序列化器会将原始 .NET 值转换为原始 JSON 值,将 .NET 数组和集合转换为 JSON 数组,并将其他所有内容转换为 JSON 对象。
Json.NET 在反序列化值时如果遇到不正确的 JSON,将会抛出错误。例如,如果序列化程序遇到带有值数组的 JSON 属性,并且匹配的 .NET 属性的类型不是集合,则将引发错误,反之亦然。
.NET | JSON |
IList, IEnumerable, IList<T>, Array | Array (properties on the collection will not be serialized) |
IDictionary, IDictionary<TKey, TValue> | Object (dictionary name/values only, properties on the dictionary will not be serialized) |
Object (more detail below) | Object |
String | String |
Byte SByte Uint16 int16 UInt16 Int32 UInt64 Int64 |
Integer |
Float Double Decimal | Float |
Enum | Integer (can be the enum value name with StringEnumConverter) |
DataTime | String (Serializing Dates in JSON) |
Byte[] | String (base 64 encoded) |
Type | String (type name) |
Guid | String |
TypeConverter (convertible to String) | String |
序列化Attributes
Attributes可用于控制 Json.NET 如何序列化和反序列化 .NET 对象。
-
JsonObjectAttribute - 放置在类上以控制如何将它们序列化为 JSON 对象。
-
JsonArrayAttribute - 放置在集合上以控制如何将它们序列化为 JSON 数组。
-
JsonDictionaryAttribute - 放置在字典上以控制如何将它们序列化为 JSON 对象。
-
JsonPropertyAttribute - 放置在字段和属性上,以控制如何将它们序列化为 JSON 对象中的属性。
-
JsonConverterAttribute - 放置在类或字段和属性上,以指定序列化期间应使用哪个 JsonConverter。
-
JsonExtensionDataAttribute - 放置在集合字段或属性上,用于将没有匹配类成员的属性反序列化到指定的集合中,并在序列化期间写入值。
-
JsonConstructorAttribute - 放置在构造函数上以指定应在反序列化期间使用它来创建类。
Json.NET Serialization Attributes
此属性上的 MemberSerialization 标志指定成员序列化是否是选择加入(成员必须具有要序列化的 JsonProperty 或 DataMember 属性)、选择退出(默认情况下会序列化所有内容,但可以使用 JsonIgnoreAttribute(Json.NET 的默认值)来忽略行为)或字段(所有公共和私有字段都被序列化,并且属性被忽略)。
JsonArrayAttribute和 JsonDictionaryAttribute用于指定类是否序列化为该集合类型。
JsonPropertyAttribute 有多种用途:
-
默认情况下,JSON 属性将与 .NET 属性具有相同的名称。此属性允许自定义名称。
-
JsonPropertyAttribute 指示当成员序列化设置为选择加入时应序列化属性。
-
它包括序列化和反序列化中的非公共属性。
-
它可用于自定义属性值的类型名称、引用、null 和默认值处理。
-
可用于自定义序列化属性名称的NamingStrategy 。
-
它可用于自定义属性的集合项 JsonConverter、类型名称处理和引用处理。
从序列化中排除字段或属性。NonSerializedAttribute可以替代JsonIgnoreAttribute
JsonConverterAttribute指定使用哪个 JsonConverter来转换对象。该属性可以放置在类或成员上。当放置在类上时,属性指定的 JsonConverter 将是序列化该类的默认方式。当属性位于字段或属性上时,指定的 JsonConverter 将始终用于序列化该值。使用 JsonConverter 的优先级是成员属性,然后是类属性,最后是传递给 JsonSerializer 的任何转换器。
实例代码如下:
1 public enum UserStatus 2 { 3 NotConfirmed, 4 Active, 5 Deleted 6 } 7 8 public class User 9 { 10 public string UserName { get; set; } 11 12 [JsonConverter(typeof(StringEnumConverter))] 13 public UserStatus Status { get; set; } 14 }
JsonExtensionDataAttribute指示 JsonSerializer将类型上没有匹配字段或属性的属性反序列化到指定集合中。在序列化期间,此集合中的值将写回实例的 JSON 对象。
示例代码如下:
1 public class DirectoryAccount 2 { 3 // normal deserialization 4 public string DisplayName { get; set; } 5 6 // these properties are set in OnDeserialized 7 public string UserName { get; set; } 8 public string Domain { get; set; } 9 10 [JsonExtensionData] 11 private IDictionary<string, JToken> _additionalData; 12 13 [OnDeserialized] 14 private void OnDeserialized(StreamingContext context) 15 { 16 // SAMAccountName is not deserialized to any property 17 // and so it is added to the extension data dictionary 18 string samAccountName = (string)_additionalData["SAMAccountName"]; 19 20 Domain = samAccountName.Split('\\')[0]; 21 UserName = samAccountName.Split('\\')[1]; 22 } 23 24 public DirectoryAccount() 25 { 26 _additionalData = new Dictionary<string, JToken>(); 27 } 28 } 29 30 string json = @"{ 31 'DisplayName': 'John Smith', 32 'SAMAccountName': 'contoso\\johns' 33 }"; 34 35 DirectoryAccount account = JsonConvert.DeserializeObject<DirectoryAccount>(json); 36 37 Console.WriteLine(account.DisplayName); 38 // John Smith 39 40 Console.WriteLine(account.Domain); 41 // contoso 42 43 Console.WriteLine(account.UserName); 44 // johns
JsonConstructorAttribute指示 JsonSerializer在反序列化类时使用特定的构造函数。它可用于使用参数化构造函数而不是默认构造函数来创建类,或者在有多个构造函数时选择要使用的特定参数化构造函数。
代码如下:
1 public class User 2 { 3 public string UserName { get; private set; } 4 public bool Enabled { get; private set; } 5 6 public User() 7 { 8 } 9 10 [JsonConstructor] 11 public User(string userName, bool enabled) 12 { 13 UserName = userName; 14 Enabled = enabled; 15 } 16 } 17 string json = @"{ 18 ""UserName"": ""domain\\username"", 19 ""Enabled"": true 20 }"; 21 22 User user = JsonConvert.DeserializeObject<User>(json); 23 24 Console.WriteLine(user.UserName); 25 // domain\username
上面大概介绍了一些Json.net的Attribute,及基本概念,下面将列举一些常用示例
序列化对象
1 public class Account 2 { 3 public string Email { get; set; } 4 public bool Active { get; set; } 5 public DateTime CreatedDate { get; set; } 6 public IList<string> Roles { get; set; } 7 } 8 9 Account account = new Account 10 { 11 Email = "james@example.com", 12 Active = true, 13 CreatedDate = new DateTime(2013, 1, 20, 0, 0, 0, DateTimeKind.Utc), 14 Roles = new List<string> 15 { 16 "User", 17 "Admin" 18 } 19 }; 20 21 string json = JsonConvert.SerializeObject(account, Formatting.Indented); 22 // { 23 // "Email": "james@example.com", 24 // "Active": true, 25 // "CreatedDate": "2013-01-20T00:00:00Z", 26 // "Roles": [ 27 // "User", 28 // "Admin" 29 // ] 30 // } 31 32 Console.WriteLine(json);
序列化集合
1 List<string> videogames = new List<string> 2 { 3 "Starcraft", 4 "Halo", 5 "Legend of Zelda" 6 }; 7 8 string json = JsonConvert.SerializeObject(videogames); 9 10 Console.WriteLine(json); 11 // ["Starcraft","Halo","Legend of Zelda"]
序列化字典
1 Dictionary<string, int> points = new Dictionary<string, int> 2 { 3 { "James", 9001 }, 4 { "Jo", 3474 }, 5 { "Jess", 11926 } 6 }; 7 8 string json = JsonConvert.SerializeObject(points, Formatting.Indented); 9 10 Console.WriteLine(json); 11 // { 12 // "James": 9001, 13 // "Jo": 3474, 14 // "Jess": 11926 15 // }
将Json序列化到文件
1 public class Movie 2 { 3 public string Name { get; set; } 4 public int Year { get; set; } 5 } 6 7 Movie movie = new Movie 8 { 9 Name = "Bad Boys", 10 Year = 1995 11 }; 12 13 // serialize JSON to a string and then write string to a file 14 File.WriteAllText(@"c:\movie.json", JsonConvert.SerializeObject(movie)); //先序列化成字符串,再到文件 15 16 // serialize JSON directly to a file 17 using (StreamWriter file = File.CreateText(@"c:\movie.json")) //将序列化直接到文件 18 { 19 JsonSerializer serializer = new JsonSerializer(); 20 serializer.Serialize(file, movie); 21 }
使用JsonConverters进行序列化
1 List<StringComparison> stringComparisons = new List<StringComparison> 2 { 3 StringComparison.CurrentCulture, 4 StringComparison.Ordinal 5 }; 6 7 string jsonWithoutConverter = JsonConvert.SerializeObject(stringComparisons); 8 9 Console.WriteLine(jsonWithoutConverter); 10 // [0,4] 11 12 string jsonWithConverter = JsonConvert.SerializeObject(stringComparisons, new StringEnumConverter()); 13 14 Console.WriteLine(jsonWithConverter); 15 // ["CurrentCulture","Ordinal"] 16 17 List<StringComparison> newStringComparsions = JsonConvert.DeserializeObject<List<StringComparison>>( 18 jsonWithConverter, 19 new StringEnumConverter()); 20 21 Console.WriteLine(string.Join(", ", newStringComparsions.Select(c => c.ToString()).ToArray())); 22 // CurrentCulture, Ordinal
序列化DataSet
1 DataSet dataSet = new DataSet("dataSet"); 2 dataSet.Namespace = "NetFrameWork"; 3 DataTable table = new DataTable(); 4 DataColumn idColumn = new DataColumn("id", typeof(int)); 5 idColumn.AutoIncrement = true; 6 7 DataColumn itemColumn = new DataColumn("item"); 8 table.Columns.Add(idColumn); 9 table.Columns.Add(itemColumn); 10 dataSet.Tables.Add(table); 11 12 for (int i = 0; i < 2; i++) 13 { 14 DataRow newRow = table.NewRow(); 15 newRow["item"] = "item " + i; 16 table.Rows.Add(newRow); 17 } 18 19 dataSet.AcceptChanges(); 20 21 string json = JsonConvert.SerializeObject(dataSet, Formatting.Indented); 22 23 Console.WriteLine(json); 24 // { 25 // "Table1": [ 26 // { 27 // "id": 0, 28 // "item": "item 0" 29 // }, 30 // { 31 // "id": 1, 32 // "item": "item 1" 33 // } 34 // ] 35 // }
反序列化对象
1 public class Account 2 { 3 public string Email { get; set; } 4 public bool Active { get; set; } 5 public DateTime CreatedDate { get; set; } 6 public IList<string> Roles { get; set; } 7 } 8 9 10 string json = @"{ 11 'Email': 'james@example.com', 12 'Active': true, 13 'CreatedDate': '2013-01-20T00:00:00Z', 14 'Roles': [ 15 'User', 16 'Admin' 17 ] 18 }"; 19 20 Account account = JsonConvert.DeserializeObject<Account>(json); 21 22 Console.WriteLine(account.Email); 23 // james@example.com
反序列化集合
1 string json = @"['Starcraft','Halo','Legend of Zelda']"; 2 3 List<string> videogames = JsonConvert.DeserializeObject<List<string>>(json); 4 5 Console.WriteLine(string.Join(", ", videogames.ToArray())); 6 // Starcraft, Halo, Legend of Zelda
反序列化字典
1 string json = @"{ 2 'href': '/account/login.aspx', 3 'target': '_blank' 4 }"; 5 6 Dictionary<string, string> htmlAttributes = JsonConvert.DeserializeObject<Dictionary<string, string>>(json); 7 8 Console.WriteLine(htmlAttributes["href"]); 9 // /account/login.aspx 10 11 Console.WriteLine(htmlAttributes["target"]); 12 // _blank
反序列化匿名类型
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
反序列化DataSet
1 string json = @"{ 2 'Table1': [ 3 { 4 'id': 0, 5 'item': 'item 0' 6 }, 7 { 8 'id': 1, 9 'item': 'item 1' 10 } 11 ] 12 }"; 13 14 DataSet dataSet = JsonConvert.DeserializeObject<DataSet>(json); 15 16 DataTable dataTable = dataSet.Tables["Table1"]; 17 18 Console.WriteLine(dataTable.Rows.Count); 19 // 2 20 21 foreach (DataRow row in dataTable.Rows) 22 { 23 Console.WriteLine(row["id"] + " - " + row["item"]); 24 } 25 // 0 - item 0 26 // 1 - item 1
题外知识,如何把DataGridView转换为DataTable?代码如下
1 DataTable dt = new DataTable(); 2 foreach(DataGridViewColumn col in dgv.Columns) 3 { 4 dt.Columns.Add(col.Name); 5 } 6 7 foreach(DataGridViewRow row in dgv.Rows) 8 { 9 DataRow dRow = dt.NewRow(); 10 foreach(DataGridViewCell cell in row.Cells) 11 { 12 dRow[cell.ColumnIndex] = cell.Value; 13 } 14 dt.Rows.Add(dRow); 15 }
从文件反序列化
1 public class Movie 2 { 3 public string Name { get; set; } 4 public int Year { get; set; } 5 } 6 7 // read file into a string and deserialize JSON to a type 8 Movie movie1 = JsonConvert.DeserializeObject<Movie>(File.ReadAllText(@"c:\movie.json")); 9 10 // deserialize JSON directly from a file 11 using (StreamReader file = File.OpenText(@"c:\movie.json")) 12 { 13 JsonSerializer serializer = new JsonSerializer(); 14 Movie movie2 = (Movie)serializer.Deserialize(file, typeof(Movie)); 15 }
反序列当前相对路径中的Json文件,代码如下:
1 Movie movie1 = JsonConvert.DeserializeObject<Movie>(File.ReadAllText(Environment.CurrentDirectory + "\\tsconfig1.json"));
填充对象
使用Json中的值填充现有对象实例
1 public class Account 2 { 3 public string Email { get; set; } 4 public bool Active { get; set; } 5 public DateTime CreatedDate { get; set; } 6 public List<string> Roles { get; set; } 7 } 8 9 Account account = new Account 10 { 11 Email = "james@example.com", 12 Active = true, 13 CreatedDate = new DateTime(2013, 1, 20, 0, 0, 0, DateTimeKind.Utc), 14 Roles = new List<string> 15 { 16 "User", 17 "Admin" 18 } 19 }; 20 21 string json = @"{ 22 'Active': false, 23 'Roles': [ 24 'Expired' 25 ] 26 }"; 27 28 JsonConvert.PopulateObject(json, account); 29 30 Console.WriteLine(account.Email); 31 // james@example.com 32 33 Console.WriteLine(account.Active); 34 // false 35 36 Console.WriteLine(string.Join(", ", account.Roles.ToArray())); 37 // User, Admin, Expired
构造函数反序列化处理设置
此示例使用ConstructorHandling设置通过其非公共构造函数成功反序列化该类。
1 public class Website 2 { 3 public string Url { get; set; } 4 5 private Website() 6 { 7 } 8 9 public Website(Website website) 10 { 11 if (website == null) 12 { 13 throw new ArgumentNullException(nameof(website)); 14 } 15 16 Url = website.Url; 17 } 18 } 19 20 21 string json = @"{'Url':'http://www.google.com'}"; 22 23 try 24 { 25 JsonConvert.DeserializeObject<Website>(json); 26 } 27 catch (Exception ex) 28 { 29 Console.WriteLine(ex.Message); 30 // Value cannot be null. 31 // Parameter name: website 32 } 33 34 Website website = JsonConvert.DeserializeObject<Website>(json, new JsonSerializerSettings 35 { 36 ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor 37 }); 38 39 Console.WriteLine(website.Url); 40 // http://www.google.com
对象创建处理设置
此示例通过将ObjectCreationHandling 设置为 Replace 来反序列化 JSON,以便集合值不会重复。
1 public class UserViewModel 2 { 3 public string Name { get; set; } 4 public IList<string> Offices { get; private set; } 5 6 public UserViewModel() 7 { 8 Offices = new List<string> 9 { 10 "Auckland", 11 "Wellington", 12 "Christchurch" 13 }; 14 } 15 } 16 17 string json = @"{ 18 'Name': 'James', 19 'Offices': [ 20 'Auckland', 21 'Wellington', 22 'Christchurch' 23 ] 24 }"; 25 26 UserViewModel model1 = JsonConvert.DeserializeObject<UserViewModel>(json); 27 28 foreach (string office in model1.Offices) 29 { 30 Console.WriteLine(office); 31 } 32 // Auckland 33 // Wellington 34 // Christchurch 35 // Auckland 36 // Wellington 37 // Christchurch 38 39 UserViewModel model2 = JsonConvert.DeserializeObject<UserViewModel>(json, new JsonSerializerSettings 40 { 41 ObjectCreationHandling = ObjectCreationHandling.Replace 42 }); 43 44 foreach (string office in model2.Offices) 45 { 46 Console.WriteLine(office); 47 } 48 // Auckland 49 // Wellington 50 // Christchurch
默认值处理设置
此示例使用DefaultValueHandling设置来不序列化具有默认值的属性。
1 public class Person 2 { 3 public string Name { get; set; } 4 public int Age { get; set; } 5 public Person Partner { get; set; } 6 public decimal? Salary { get; set; } 7 } 8 9 Person person = new Person(); 10 11 string jsonIncludeDefaultValues = JsonConvert.SerializeObject(person, Formatting.Indented); 12 13 Console.WriteLine(jsonIncludeDefaultValues); 14 // { 15 // "Name": null, 16 // "Age": 0, 17 // "Partner": null, 18 // "Salary": null 19 // } 20 21 string jsonIgnoreDefaultValues = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings 22 { 23 DefaultValueHandling = DefaultValueHandling.Ignore 24 }); 25 26 Console.WriteLine(jsonIgnoreDefaultValues); 27 // {}
缺少成员处理设置
此示例尝试在MissingMemberHandling 设置为错误且 JSON 属性与成员不匹配的情况下反序列化 JSON,从而导致异常。
1 public class Account 2 { 3 public string FullName { get; set; } 4 public bool Deleted { get; set; } 5 } 6 7 string json = @"{ 8 'FullName': 'Dan Deleted', 9 'Deleted': true, 10 'DeletedDate': '2013-01-20T00:00:00' 11 }"; 12 13 try 14 { 15 JsonConvert.DeserializeObject<Account>(json, new JsonSerializerSettings 16 { 17 MissingMemberHandling = MissingMemberHandling.Error 18 }); 19 } 20 catch (JsonSerializationException ex) 21 { 22 Console.WriteLine(ex.Message); 23 // Could not find member 'DeletedDate' on object of type 'Account'. Path 'DeletedDate', line 4, position 23. 24 }
空值处理设置
此示例将对象序列化为 JSON,并将NullValueHandling 设置为“忽略”,以便具有默认值的属性不会包含在 JSON 结果中。
1 public class Person 2 { 3 public string Name { get; set; } 4 public int Age { get; set; } 5 public Person Partner { get; set; } 6 public decimal? Salary { get; set; } 7 } 8 9 10 Person person = new Person 11 { 12 Name = "Nigal Newborn", 13 Age = 1 14 }; 15 16 string jsonIncludeNullValues = JsonConvert.SerializeObject(person, Formatting.Indented); 17 18 Console.WriteLine(jsonIncludeNullValues); 19 // { 20 // "Name": "Nigal Newborn", 21 // "Age": 1, 22 // "Partner": null, 23 // "Salary": null 24 // } 25 26 string jsonIgnoreNullValues = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings 27 { 28 NullValueHandling = NullValueHandling.Ignore 29 }); 30 31 Console.WriteLine(jsonIgnoreNullValues); 32 // { 33 // "Name": "Nigal Newborn", 34 // "Age": 1 35 // }
标签:Newtonsoft,string,get,用法,Json,set,new,序列化,public From: https://www.cnblogs.com/davisdabing/p/17811281.html