C# json使用之Json.NET(5)——特别篇

2018年8月3日 0 条评论 1.26k 次阅读 0 人点赞

以下内容介绍了json.NET的性能优化问题、使用JSON模式验证JSON、手动读写JSON,Json.NET提供了JsonReader和JsonWriter类、json和xml之间的转换。

性能提示

开箱即用的Json.NET比DataContractJsonSerializer和JavaScriptSerializer更快。 这里有一些提示,使它更快。

优化内存使用

为了使应用程序保持一致,最重要的是最小化.NET框架执行垃圾收集所花费的时间。 在进行垃圾收集时,分配太多对象或分配非常大的对象可能会减慢甚至停止应用程序。

为了最小化内存使用和分配的对象数量,Json.NET支持直接对流进行序列化和反序列化。 一次读取或写入JSON,而不是将整个JSON字符串加载到内存中,在处理大小超过85kb的JSON文档时尤其重要,以避免JSON字符串在大对象堆中结束。

JsonConverters

将JsonConverter传递给SerializeObject或DeserializeObject提供了一种完全更改对象序列化方式的简单方法。 但是,有少量的开销; 为每个值调用CanConvert方法以检查是否应该由JsonConverter处理序列化。

有两种方法可以继续使用JsonConverters而无需任何开销。 最简单的方法是使用JsonConverterAttribute指定JsonConverter。 此属性告诉序列化程序在序列化和反序列化类型时始终使用该转换器,而不进行检查。

如果要转换的类不是您自己的类,并且您无法使用属性,则仍可以通过创建自己的IContractResolver来使用JsonConverter。

上例中的IContractResolver将设置所有DateTimes以使用JavaScriptDateConverter。

Manually Serialize

读取和写入JSON的绝对最快的方法是直接使用JsonTextReader / JsonTextWriter手动序列化类型。 使用读取器或编写器直接跳过序列化器的任何开销,例如反射。

如果性能很重要并且您不介意编写更多代码来获取它,那么这是您的最佳选择。 您可以在此处阅读有关使用JsonReader / JsonWriter的更多信息:基本解释和编写JSON

Benchmarks

https://www.newtonsoft.com/json/help/media/performance.png

使用JSON模式验证JSON

Json.NET通过JsonSchema和JsonValidatingReader类支持JSON Schema标准。 它位于Newtonsoft.Json.Schema命名空间下。

JSON Schema用于验证一块JSON的结构和数据类型,类似于XML Schema for XML。 您可以在json-schema.org上阅读有关JSON Schema的更多信息。

已过时。 JSON Schema验证已移至其自己的包中。 有关详细信息,请参阅http://www.newtonsoft.com/jsonschema。

使用JSON模式进行验证

检查JSON是否有效的最简单方法是将JSON加载到JObject或JArray中,然后将IsValid(JToken,JsonSchema)方法与JSON Schema一起使用。

要获取验证错误消息,请使用IsValid(JToken,JsonSchema,IList <String>)或Validate(JToken,JsonSchema,ValidationEventHandler)重载。

内部IsValid使用JsonValidatingReader来执行JSON Schema验证。 为了省略将JSON加载到JObject / JArray,验证JSON,然后将JSON反序列化为类的开销,JsonValidatingReader可以与JsonSerializer一起使用,以在反序列化对象时验证JSON。

创建JSON模式

获取JsonSchema对象的最简单方法是从字符串或文件加载它。

也可以在代码中创建JsonSchema对象。

Basic Reading and Writing JSON

为了手动读写JSON,Json.NET提供了JsonReader和JsonWriter类。

JsonTextReader and JsonTextWriter

JsonReader和JsonWriter是低级类,主要供Json.NET内部使用。 要快速使用JSON,建议使用序列化程序 - 序列化和反序列化JSON - 或使用LINQ to JSON。

JsonTextReader和JsonTextWriter用于读写JSON文本。 JsonTextWriter上有许多设置来控制JSON在写入时的格式。 这些选项包括格式,缩进字符,缩进计数和引号字符。

JsonTextReader上有设置,用于在读取文本值时读取不同的日期格式,时区和文化。

JTokenReader and JTokenWriter

JTokenReader和JTokenWriter读写LINQ to JSON对象。 它们位于Newtonsoft.Json.Linq命名空间中。 这些对象允许您将LINQ to JSON对象与读取和写入JSON的对象一起使用,例如JsonSerializer。 例如,您可以从LINQ to JSON对象反序列化为常规.NET对象,反之亦然。

在JSON和XML之间转换

Json.NET支持使用XmlNodeConverter将JSON转换为XML,反之亦然。

在两者之间进行转换时,都会保留元素,属性,文本,注释,字符数据,处理指令,命名空间和XML声明。 唯一需要注意的是,当它们组合成一个数组时,可能会丢失同一级别的不同命名节点的顺序。

转换规则

  • 元素保持不变。

  • 属性以@为前缀,应位于对象的开头。

  • 单个子文本节点是直接针对元素的值,否则通过#text访问它们。

  • XML声明和处理指令以?为前缀。

  • 字符数据,注释,空格和重要的空白节点分别通过#cdata-section,#comment,#whitespace和#significant-whitespace进行访问。

  • 在同一级别具有相同名称的多个节点被组合在一起成为一个数组。

  • 空元素为null。

如果从JSON创建的XML与您想要的不匹配,那么您将需要手动转换它。 执行此操作的最佳方法是将JSON加载到LINQ to JSON对象(如JObject或JArray),然后使用LINQ创建XDocument。 使用LINQ和XDocument创建JObject或JArray的相反过程也可以。 您可以在此处找到有关在LINQ中使用LINQ to JSON的更多信息。

在您的应用程序中使用的Json.NET版本将更改可用的XML转换方法。 当框架支持XmlDocument时,SerializeXmlNode / DeserializeXmlNode可用; 当框架支持XDocument时,SerializeXNode / DeserializeXNode可用。

SerializeXmlNode

JsonConvert有两个辅助方法,用于在JSON和XML之间进行转换。 第一个是SerializeXmlNode()。 此方法采用XmlNode并将其序列化为JSON文本。

由于同一级别具有相同名称的多个节点组合在一起形成一个数组,因此转换过程可以根据节点数生成不同的JSON。 例如,如果用户的某些XML具有单个<Role>节点,则该角色将是针对JSON“Role”属性的文本,但如果用户具有多个<Role>节点,则角色值将放入 一个JSON数组。

要解决此问题,可以添加自定义XML属性以强制创建JSON数组。

DeserializeXmlNode

JsonConvert上的第二个辅助方法是DeserializeXmlNode()。 此方法接受JSON文本并将其反序列化为XmlNode。

因为有效的XML必须有一个根元素,所以传递给DeserializeXmlNode的JSON应该在根JSON对象中有一个属性。 如果根JSON对象具有多个属性,则应使用也采用元素名称的重载。 具有该名称的根元素将插入到反序列化的XmlNode中。

文章来源:源代码,欢迎分享,转载请保留出处。

原文地址:https://www.vcblog.top/article/460/

技术重在于积累,不要灰心,希望在明天!

文章评论(0)