序列化是将对象转换成易于传输的形式的过程。例如,可以序列化对象,并使用 HTTP 通过 Internet 在客户端和服务器之间进行传输。另一方面,反序列化在流中重新构建对象。
XML 序列化只将对象的公共字段和属性值序列化为 XML 流。XML 序列化不包括类型信息。例如,如果 Library 命名空间中存在 Book 对象,则不能保证将它反序列化为同一类型的对象。
注意: |
---|
XML 序列化不能转换方法、索引器、私有字段或只读属性(只读集合除外)。要序列化对象的所有公共和私有字段和属性,请使用 BinaryFormatter 而不要使用 XML 序列化。
|
XML 序列化中的中心类是 XmlSerializer 类,该类中最重要的方法是 Serialize 和 Deserialize 方法。XmlSerializer 创建 C# 文件并将其编译为 .dll 文件,以执行此序列化。
对象中的数据是用编程语言构造来描述的,如类、字段、属性 (Property)、基元类型、数组,甚至 XmlElement 或 XmlAttribute 对象形式的嵌入 XML。可以创建自己的用属性 (Attribute) 批注的类,也可以使用 XML 架构定义工具生成基于现有 XML 架构的类。
如果有 XML 架构,则可以运行 XML 架构定义工具生成一组类,将这组类的类型强制为此架构,并用属性 (Attribute) 进行批注。当序列化这种类的实例时,生成的 XML 符合 XML 架构。对于这种类,可以采用易于操作的对象模型进行编程,同时确保生成的 XML 符合 XML 架构。这是使用 .NET Framework 中的其他类(如 XmlReader 和 XmlWriter 类)分析和编写 XML 流的另一种方法。
属性可控制 XmlSerializer 类生成的 XML 流,从而允许您设置 XML 流的 XML 命名空间、元素名称、属性名称等。
XmlSerializer 类可以进一步序列化对象并生成编码的 SOAP XML 流。XmlSerializer 类生成由 XML Web services 创建并传递给 XML Web services 的 SOAP 消息。要控制 SOAP 消息,可以将属性应用于在 XML Web services 文件 (.asmx) 中找到的类、返回值、参数和字段。由于 XML Web services 可以使用文本或编码的 SOAP 样式,因此既可以使用“用来控制 XML 序列化的属性”中列出的属性,也可以使用“用来控制编码的 SOAP 序列化的属性”中列出的属性。
XmlSerializer 应用程序的安全注意事项
创建应用程序来使用 XmlSerializer 时,应注意以下几项及其含义:
-
XmlSerializer 在 TEMP 环境变量命名的目录中创建 C# (.cs) 文件并将其编译为 .dll 文件;这些 DLL 文件将进行序列化。
注意: 可预先生成这些序列化程序集,并使用 SGen.exe 工具对它们进行签名。这不适用于 Web 服务的服务器。也就是说,这只适用于客户端用法和手动序列化。
代码和 DLL 在创建和编译时易受恶意进程破坏。当使用的计算机运行 Microsoft Windows NT 4.0 或更高版本时,可能有两个或多个用户共享 TEMP 目录。如果两个帐户的安全权限不同,且权限较高的帐户使用 XmlSerializer 运行应用程序,则共享 TEMP 目录是危险的。在这种情况下,一个用户可能因替换已编译的 .cs 或 .dll 文件而违反计算机的安全性。要消除这一问题,应始终确保计算机上的每个帐户具有各自的配置文件。默认情况下,TEMP 环境变量为每个帐户指向不同的目录。
-
如果恶意用户将连续的 XML 数据流发送至 Web 服务器(拒绝服务攻击),则 XmlSerializer 会持续处理数据,直至计算机资源不足。
如果您使用的计算机运行了 Internet 信息服务 (IIS),并且您的应用程序在 IIS 内运行,则可消除这种攻击。IIS 提供了一种网关,这种网关不处理长度超过设定量(默认值为 4 KB)的流。如果创建的应用程序不使用 IIS 并且使用 XmlSerializer 进行反序列化,则您应当实现类似的网关,以防止拒绝服务攻击。
-
XmlSerializer 使用提供给它的任何类型序列化数据并运行任何代码。
恶意对象造成威胁的方式有两种。它可以运行恶意代码,也可以将恶意代码插入 XmlSerializer 所创建的 C# 文件。在第一种情况下,如果恶意对象试图运行破坏性的过程,代码访问安全有助于防止发生任何损坏。在第二种情况下,理论上讲恶意对象有可能以某种方式将代码插入 XmlSerializer 所创建的 C# 文件。尽管这一问题已得到彻底检查并且认为不可能发生这种攻击,但还是应当采取防范措施,一定不要使用未知和不受信任的类型来序列化数据。
-
已序列化的敏感数据可能容易受到攻击。
XmlSerializer 序列化数据后,数据可以存储在 XML 文件或其他数据存储区中。如果数据存储区可供其他进程使用或者可在 Intranet 或 Internet 上看见,则数据可能被盗和恶意使用。例如,如果您创建一个应用程序来序列化包含信用卡号码的订单,则数据是高度敏感的。为防止被盗和恶意使用,应始终保护您的数据存储区并采取步骤保持其私密性。
可序列化的项
可使用 XmLSerializer 类对以下项进行序列化:
-
公共类的公共读/写属性和字段。
-
实现 ICollection 或 IEnumerable 的类。
注意: 仅序列化集合,不序列化公共属性。
-
XmlElement 对象。
-
XmlNode 对象。
-
DataSet 对象。
使用 XML 序列化的优点
将对象序列化为 XML 时,XmlSerializer 类可为您提供完整而灵活的控制。如果要创建 XML Web services,可以将控制序列化的属性应用于类和成员,以确保 XML 输出符合特定架构。
例如,XmlSerializer 可让您:
-
指定字段或属性 (Property) 是否应编码为属性 (Attribute) 或元素。
-
指定要使用的 XML 命名空间。
-
指定字段或属性 (Property) 名称不恰当时的元素或属性 (Attribute) 名称。
XML 序列化的另一个优点是,只要生成的 XML 流符合给定的架构,就对开发的应用程序没有任何约束。假设有一个架构,它用于描述书籍。它提供有书名、作者、出版商和 ISBN 号元素。您可以开发一个应用程序来以任何想要的方式(例如以书籍订单或书籍库存方式)处理 XML 数据。在任一种情况下,唯一的要求是 XML 流符合指定的 XML 架构定义语言 (XSD) 架构。
XML 序列化注意事项
使用 XmlSerializer 类时,应注意以下事项:
-
Sgen.exe 工具特别设计为生成序列化程序集,以获得最佳性能。
-
序列化数据只包含数据本身和类的结构。类型标识和程序集信息不包括在内。
-
只能序列化公共属性和字段。属性必须具有公共访问器(get 和 set 方法)。如果必须序列化非公共数据,请使用 BinaryFormatter 类而不是 XML 序列化。
-
类必须具有默认构造函数才能被 XmlSerializer 序列化。
-
方法不能被序列化。
-
如果可实现 IEnumerable 或 ICollection 的类满足特定要求,则 XmlSerializer 可以以不同方式处理这些类,如下所述。
实现 IEnumerable 的类必须实现采用单个参数的公共 Add 方法。Add 方法的参数必须与从 IEnumerator.Current 属性返回的类型一致(多态),该属性是从 GetEnumerator 方法返回的。
除了 IEnumerable 之外,实现 ICollection(如 CollectionBase)的类还必须有一个采用整数的公共 Item 索引属性(在 C# 中为索引器),而且必须有一个 integer 类型的公共 Count 属性。传递给 Add 方法的参数的类型必须与从 Item 属性返回的类型相同,或者为此类型的基之一。
对于实现 ICollection 的类,可从已编制索引的 Item 属性检索要序列化的值,而不是通过调用 GetEnumerator。此外,除了返回另一个集合类(实现 ICollection 的类)的公共字段外,公共字段和属性不会被序列化。