JSON(JavaScript Object Notation)是一种轻量级的数据交换格式, 人类很容易读写。 机器很容易解析和生成。 它是基于JavaScript编程语言的一个子集,标准ECMA-262第3版 - 1999年12月。JSON是一种完全独立于语言的文本格式,但使用C语言系列程序员熟悉的约定,包括C语言 ,C ++,C#,Java,JavaScript,Perl,Python等等。 这些属性使JSON成为理想的数据交换语言。
Json.NET是一种流行的.NET高性能JSON框架,在.net中可以方便的进行json操作,以下内容翻译自官方文档。
在C#中使用Json.NET时需要在包管理器中引入Newtonsoft的Json.NET。
灵活的JSON序列化程序,用于在.NET对象和JSON之间进行转换
LINQ to JSON用于手动读写JSON
高性能:比.NET的内置JSON序列化器更快
写缩进,易于阅读的JSON
将JSON转换为XML或从XML转换
支持.NET 2,.NET 3.5,.NET 4,.NET 4.5,Silverlight,Windows Phone和Windows 8 Store
当您正在阅读或编写的JSON紧密映射到.NET类时,Json.NET中的JSON序列化程序是一个不错的选择。
LINQ to JSON适用于您只对从JSON获取值感兴趣的情况,您没有要序列化或反序列化的类,或者JSON与您的类完全不同,您需要手动读取和写入对象。
在JSON文本和.NET对象之间转换的最快方法是使用JsonSerializer
。 JsonSerializer
通过将.NET对象属性名称映射到JSON属性名称并进行赋值,将.NET对象转换为其JSON对象并再次返回。
JsonConvert
对于要与JSON字符串进行转换的简单方案,JsonConvert上的SerializeObject()和DeserializeObject()方法提供了一个易于使用的JsonSerializer包装器。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
Product product = new Product();
product.Name = "Apple";
product.ExpiryDate = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };
string output = JsonConvert.SerializeObject(product);
//{
// "Name": "Apple",
// "ExpiryDate": "2008-12-28T00:00:00",
// "Price": 3.99,
// "Sizes": [
// "Small",
// "Medium",
// "Large"
// ]
//}
Product deserializedProduct = JsonConvert.DeserializeObject
|
SerializeObject和DeserializeObject都有重载,它们带有JsonSerializerSettings对象。 JsonSerializerSettings允许您使用下面列出的许多JsonSerializer设置,同时仍使用简单的序列化方法。
JsonSerializer
为了更好地控制对象的序列化方式,可以直接使用JsonSerializer。 JsonSerializer能够通过JsonTextReader和JsonTextWriter直接读取和写入JSON文本到流。 也可以使用其他类型的JsonWriters,例如JTokenReader / JTokenWriter,将LINQ对象转换为JSON对象,或使用BsonReader / BsonWriter,以转换为BSON和从BSON转换。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
Product product = new Product();
product.ExpiryDate = new DateTime(2008, 12, 28);
JsonSerializer serializer = new JsonSerializer();
serializer.Converters.Add(new JavaScriptDateTimeConverter()); //转为JavaScript的时间格式
serializer.NullValueHandling = NullValueHandling.Ignore; //忽略空值
using (StreamWriter sw = new StreamWriter(@"c:\json.txt"))
using (JsonWriter writer = new JsonTextWriter(sw))
{
serializer.Serialize(writer, product);
// {"ExpiryDate":new Date(1230375600000),"Price":0}
}
|
JsonSerializer上有许多属性来自定义它如何序列化JSON。 这些也可以通过JsonSerializerSettings重载与JsonConvert上的方法一起使用。您可以在此处阅读有关可用JsonSerializer设置的更多信息:序列化设置。
JsonSerializer上有许多属性来自定义它如何序列化JSON。 这些也可以通过JsonSerializerSettings重载与JsonConvert上的方法一起使用。
DateFormatHandling
DateFormatHandling
控制日期的序列化方式。
成员属性 | 描述 |
IsoDateFormat | 默认情况下,Json.NET以ISO 8601格式写入日期,例如“2012-03-21T05:40Z”。 |
MicrosoftDateFormat | 日期以Microsoft JSON格式编写,例如“\/日期(1198908717056)\/”。 |
MissingMemberHandling
MissingMemberHandling
控制成员缺失的方式,例如 JSON包含一个属性,该属性不是对象的成员,在反序列化期间处理。
成员属性 | 描述 |
Ignore | 默认情况下,如果在反序列化期间没有要为其值设置的字段或属性,Json.NET将忽略JSON。 |
Error | 在反序列化期间缺少成员时提示Json.NET错误。 |
ReferenceLoopHandling
ReferenceLoopHandling
控制循环引用对象的方式,例如 通过Manager属性引用自身的Person对象被序列化。Equals(Object)方法用于测试对象是否在循环引用中。
默认情况下,Object.Equals(Object)将测试引用对于引用类型是否相等,私有值和公共值对于值类型是否相等。 类和结构可以覆盖此方法。
成员属性 | 描述 |
Error | 默认情况下,如果遇到引用循环,Json.NET将会出错(否则序列化程序将进入无限循环)。 |
Ignore | Json.NET将忽略引用循环中的对象而不是序列化它们。 第一次遇到对象时,它将像往常一样进行序列化,但如果对象作为自身的子对象遇到,则序列化程序将跳过序列化它。 |
Serialize | 此选项强制Json.NET序列化引用循环中的对象。 如果对象嵌套但不是无限的,这很有用。 |
ReferenceLoopHandling可以在调用序列化程序时用作参数,可以使用ItemReferenceLoopHandling在对象的属性或集合的项目上设置,使用ReferenceLoopHandling在属性上自定义,或者使用ItemReferenceLoopHandling在属性的对象属性或集合项目上自定义。
NullValueHandling
NullValueHandling
控制在序列化期间如何处理.NET对象上的空值以及在反序列化期间如何处理JSON中的空值。
成员属性 | 描述 |
Include | 默认情况下,Json.NET在序列化时将空值写入JSON,并在反序列化时将空值设置为字段/属性。 |
Ignore | 如果序列化时.NET值为null,Json.NET将跳过编写JSON属性,如果反序列化时JSON属性为null,则跳过设置字段/属性。 |
DefaultValueHandling
DefaultValueHandling
控制Json.NET在序列化和反序列化时如何使用.NET DefaultValueAttribute设置的默认值。
成员属性 | 描述 |
Include | 默认情况下,如果值与字段/属性的默认值相同,Json.NET将在序列化时将字段/属性值写入JSON。 如果JSON值与默认值相同,Json.NET反序列化器将继续设置字段/属性。 |
Ignore | 如果值与字段/属性的默认值相同,Json.NET将跳过将字段/属性值写入JSON,如果属性存在,则跳过DefaultValueAttribute中指定的自定义值。 如果JSON值与默认值相同,Json.NET反序列化器将跳过设置.NET对象的字段/属性。 |
也可以使用JsonPropertyAttribute在各个属性上自定义DefaultValueHandling。
ObjectCreationHandling
ObjectCreationHandling
控制在反序列化期间如何创建和反序列化对象。
成员属性 | 描述 |
Auto | 默认情况下,Json.NET将尝试将JSON值设置为现有对象,并在反序列化期间将JSON值添加到现有集合。 |
Reuse | 与auto相同的行为。 |
Replace | 在反序列化期间为其设置值之前,Json.NET将始终重新创建对象和集合。 |
也可以使用JsonPropertyAttribute在各个属性上自定义ObjectCreationHandling。
TypeNameHandling
当您的应用程序从外部源反序列化JSON时,应谨慎使用TypeNameHandling。
在使用TypeNameHandling.None以外的值进行反序列化时,应使用自定义ISerializationBinder验证传入类型。
TypeNameHandling
控制Json.NET是否在使用$type
属性进行序列化时包含.NET类型名称,并从该属性读取.NET类型名称以确定在反序列化期间要创建的类型。
像$type
这样的元数据属性必须位于JSON对象的开头,以便在反序列化期间成功检测到。 如果无法控制JSON对象中的属性顺序,则可以使用MetadataPropertyHandling
来删除此限制。
可以通过创建自己的ISerializationBinder
来自定义和验证$type
属性的值。
成员属性 | 描述 |
None | 默认情况下,Json.NET在反序列化期间不读取或写入类型名称。 |
Objects | Json.NET将为对象编写和使用类型名称,而不是集合。 |
Arrays | Json.NET将为集合编写和使用类型名称,而不是对象。 |
Auto | Json.NET将检查对象/集合是否与其声明的属性匹配,如果它们不匹配则写入类型名称,例如 具有Mammal类型的属性具有已分配的派生实例。 自动序列化/反序列化时,自动将确保不丢失类型信息,而无需为每个对象写入类型名称。 |
All | Json.NET将为对象和集合编写和使用类型名称。 |
调用序列化程序时,TypeNameHandling可用作参数,可以使用ItemTypeNameHandling在对象的属性或集合项上设置,使用TypeNameHandling在属性上自定义,或使用ItemTypeNameHandling在属性的对象属性或集合项上自定义。
TypeNameAssemblyFormat
FormatterAssemblyStyle
控制在序列化期间如何写入类型名称。
成员属性 | 描述 |
Simple | 默认情况下,Json.NET使用类型编写部分程序集名称,例如 System.Data.DataSet,System.Data。 请注意,Silverlight和Windows Phone无法使用此格式。 |
Full | Json.NET将编写完整的程序集名称,包括版本号,文化和公钥令牌。 |
SerializationBinder
ISerializationBinder
用于解析.NET类型以在序列化期间键入名称,并在反序列化期间为.NET类型键入名称。
如果启用了TypeNameHandling
,则强烈建议出于安全原因使用自定义ISerializationBinder
来验证传入的类型名称。
MetadataPropertyHandling
MetadataPropertyHandling控制在反序列化期间如何读取元类型属性(如$ type
和$ id
)。
出于性能原因,默认情况下,JsonSerializer假定任何元数据属性都位于JSON对象的开头。 如果您无法保证JSON中的属性顺序是反序列化,那么MetadataPropertyHandling.ReadAhead会以某些性能为代价来消除此限制。
成员属性 | 描述 |
Default | 默认情况下,Json.NET只会读取位于JSON对象开头的元数据属性。 |
ReadAhead | Json.NET将查找位于JSON对象中任何位置的元数据属性。 |
Ignore | Json.NET将忽略元数据属性。 |
ConstructorHandling
ConstructorHandling
控制在反序列化期间初始化对象时如何使用构造函数。
成员属性 | 描述 |
Default | 默认情况下,Json.NET将首先查找标记有JsonConstructorAttribute的构造函数,然后查找公共默认构造函数(不带任何参数的构造函数),然后检查该类是否具有带参数的单个公共构造函数,最后检查 对于非公共默认构造函数。 如果该类有多个带参数的公共构造函数,则会抛出错误。 这可以通过使用JsonConstructorAttribute标记其中一个构造函数来修复。 |
AllowNonPublicDefaultConstructor | 如果可用,Json.NET将在带有参数的构造函数之前使用类私有默认构造函数。 |
Converters
这是将在序列化和反序列化期间使用的JsonConverters的集合。
JsonConverter允许在序列化期间手动编写JSON,并在反序列化期间读取。这对于特别复杂的JSON结构或者当您想要更改类型的序列化方式时非常有用。
将JsonConverter添加到JsonSerializer后,将使用其CanConvert检查正在序列化/反序列化的每个值,以查看是否应该使用它。如果CanConvert返回true,则JsonConverter将用于读取或写入该值的JSON。请注意,虽然JsonConverter使您可以完全控制该值JSON,但许多Json.NET序列化功能不再可用,如类型名称和引用处理。
JsonConverters可以在调用序列化程序时用作参数,可以使用JsonConverterAttribute在对象或属性上设置,使用ItemConverterType在对象的属性或集合的项目上设置,或使用ItemConverterType在属性的对象属性或集合项目上设置。
要从JsonConverter类创建自己的自定义转换器继承。 阅读下面有关内置JsonConverters的更多信息:
Serializing Dates in JSON、Converting between JSON and XML、CustomCreationConverter、StringEnumConverter。
ContractResolver
对于每种.NET类型,JsonSerializer都会根据应用于类的类型元数据和属性,创建一个如何序列化和反序列化类型的契约。 指定自定义IContractResolver允许创建自定义的合同。
在此处阅读有关合同解析器的更多信息:Serialization using ContractResolver。
TraceWriter
Json.NET序列化程序支持使用ITraceWriter接口进行日志记录和调试。 通过分配跟踪编写器,您可以在序列化和反序列化JSON时调试Json.NET序列化程序中发生的事情。
在这里阅读有关TraceWriters的更多信息:Debugging with Serialization Tracing。
Error
Error事件可以在序列化期间捕获错误,并处理事件并继续序列化,或者让错误冒出来并抛给应用程序。
阅读有关错误处理的更多信息:Serialization Error Handling。