C# json使用之Json.NET(1)

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序列化程序,用于在.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

在JSON文本和.NET对象之间转换的最快方法是使用JsonSerializerJsonSerializer通过将.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(output);

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设置的更多信息:序列化设置。

Serialization Settings,序列化设置

JsonSerializer上有许多属性来自定义它如何序列化JSON。 这些也可以通过JsonSerializerSettings重载与JsonConvert上的方法一起使用。

  1. DateFormatHandling

    DateFormatHandling控制日期的序列化方式。

    成员属性 描述
    IsoDateFormat 默认情况下,Json.NET以ISO 8601格式写入日期,例如“2012-03-21T05:40Z”。
    MicrosoftDateFormat 日期以Microsoft JSON格式编写,例如“\/日期(1198908717056)\/”。
  2. MissingMemberHandling

    MissingMemberHandling控制成员缺失的方式,例如 JSON包含一个属性,该属性不是对象的成员,在反序列化期间处理。

    成员属性 描述
    Ignore 默认情况下,如果在反序列化期间没有要为其值设置的字段或属性,Json.NET将忽略JSON。
    Error 在反序列化期间缺少成员时提示Json.NET错误。
  3. ReferenceLoopHandling

    ReferenceLoopHandling控制循环引用对象的方式,例如 通过Manager属性引用自身的Person对象被序列化。Equals(Object)方法用于测试对象是否在循环引用中。

    默认情况下,Object.Equals(Object)将测试引用对于引用类型是否相等,私有值和公共值对于值类型是否相等。 类和结构可以覆盖此方法。

    成员属性 描述
    Error 默认情况下,如果遇到引用循环,Json.NET将会出错(否则序列化程序将进入无限循环)。
    Ignore Json.NET将忽略引用循环中的对象而不是序列化它们。 第一次遇到对象时,它将像往常一样进行序列化,但如果对象作为自身的子对象遇到,则序列化程序将跳过序列化它。
    Serialize 此选项强制Json.NET序列化引用循环中的对象。 如果对象嵌套但不是无限的,这很有用。

    ReferenceLoopHandling可以在调用序列化程序时用作参数,可以使用ItemReferenceLoopHandling在对象的属性或集合的项目上设置,使用ReferenceLoopHandling在属性上自定义,或者使用ItemReferenceLoopHandling在属性的对象属性或集合项目上自定义。

  4. NullValueHandling

    NullValueHandling控制在序列化期间如何处理.NET对象上的空值以及在反序列化期间如何处理JSON中的空值。

    成员属性 描述
    Include 默认情况下,Json.NET在序列化时将空值写入JSON,并在反序列化时将空值设置为字段/属性。
    Ignore 如果序列化时.NET值为null,Json.NET将跳过编写JSON属性,如果反序列化时JSON属性为null,则跳过设置字段/属性。
  5. DefaultValueHandling

    DefaultValueHandling控制Json.NET在序列化和反序列化时如何使用.NET DefaultValueAttribute设置的默认值。

    成员属性 描述
    Include 默认情况下,如果值与字段/属性的默认值相同,Json.NET将在序列化时将字段/属性值写入JSON。 如果JSON值与默认值相同,Json.NET反序列化器将继续设置字段/属性。
    Ignore 如果值与字段/属性的默认值相同,Json.NET将跳过将字段/属性值写入JSON,如果属性存在,则跳过DefaultValueAttribute中指定的自定义值。 如果JSON值与默认值相同,Json.NET反序列化器将跳过设置.NET对象的字段/属性。

    也可以使用JsonPropertyAttribute在各个属性上自定义DefaultValueHandling。

  6. ObjectCreationHandling

    ObjectCreationHandling控制在反序列化期间如何创建和反序列化对象。

    成员属性 描述
    Auto 默认情况下,Json.NET将尝试将JSON值设置为现有对象,并在反序列化期间将JSON值添加到现有集合。
    Reuse 与auto相同的行为。
    Replace 在反序列化期间为其设置值之前,Json.NET将始终重新创建对象和集合。

    也可以使用JsonPropertyAttribute在各个属性上自定义ObjectCreationHandling。

  7. 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在属性的对象属性或集合项上自定义。

  8. TypeNameAssemblyFormat

    FormatterAssemblyStyle控制在序列化期间如何写入类型名称。

    成员属性 描述
    Simple 默认情况下,Json.NET使用类型编写部分程序集名称,例如 System.Data.DataSet,System.Data。 请注意,Silverlight和Windows Phone无法使用此格式。
    Full Json.NET将编写完整的程序集名称,包括版本号,文化和公钥令牌。
  9. SerializationBinder

    ISerializationBinder用于解析.NET类型以在序列化期间键入名称,并在反序列化期间为.NET类型键入名称。

    如果启用了TypeNameHandling,则强烈建议出于安全原因使用自定义ISerializationBinder来验证传入的类型名称。

  10. MetadataPropertyHandling

    MetadataPropertyHandling控制在反序列化期间如何读取元类型属性(如$ type$ id)。

    出于性能原因,默认情况下,JsonSerializer假定任何元数据属性都位于JSON对象的开头。 如果您无法保证JSON中的属性顺序是反序列化,那么MetadataPropertyHandling.ReadAhead会以某些性能为代价来消除此限制。

    成员属性 描述
    Default 默认情况下,Json.NET只会读取位于JSON对象开头的元数据属性。
    ReadAhead Json.NET将查找位于JSON对象中任何位置的元数据属性。
    Ignore Json.NET将忽略元数据属性。
  11. ConstructorHandling

    ConstructorHandling控制在反序列化期间初始化对象时如何使用构造函数。

    成员属性 描述
    Default 默认情况下,Json.NET将首先查找标记有JsonConstructorAttribute的构造函数,然后查找公共默认构造函数(不带任何参数的构造函数),然后检查该类是否具有带参数的单个公共构造函数,最后检查 对于非公共默认构造函数。 如果该类有多个带参数的公共构造函数,则会抛出错误。 这可以通过使用JsonConstructorAttribute标记其中一个构造函数来修复。
    AllowNonPublicDefaultConstructor 如果可用,Json.NET将在带有参数的构造函数之前使用类私有默认构造函数。
  12. 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。

  13. ContractResolver

    对于每种.NET类型,JsonSerializer都会根据应用于类的类型元数据和属性,创建一个如何序列化和反序列化类型的契约。 指定自定义IContractResolver允许创建自定义的合同。

    在此处阅读有关合同解析器的更多信息:Serialization using ContractResolver。

  14. TraceWriter

    Json.NET序列化程序支持使用ITraceWriter接口进行日志记录和调试。 通过分配跟踪编写器,您可以在序列化和反序列化JSON时调试Json.NET序列化程序中发生的事情。

    在这里阅读有关TraceWriters的更多信息:Debugging with Serialization Tracing。

  15. Error

    Error事件可以在序列化期间捕获错误,并处理事件并继续序列化,或者让错误冒出来并抛给应用程序。

    阅读有关错误处理的更多信息:Serialization Error Handling。

你可能感兴趣的:(C#,c#,json)