Microsoft .NET Framework 提供了用于创建和显示高质量文档的强大环境。 增强的功能支持固定文档和流文档、高级查看控件以及强大的 2D 和 3D 图形功能,可将 .NET Framework 应用程序提升到一个新的质量和用户体验级别。 能够灵活管理文档的内存表示形式是 .NET Framework 的核心功能,而几乎所有应用程序都需要能够有效地从数据存储中保存和加载文档。 将文档从内部内存中表示形式转换为外部数据存储的过程称为序列化。 读取数据存储和重新创建原始内存中实例的反向过程称为反序列化。
关于文档序列化
理想情况下,序列化和反序列化文档的过程对应用程序而言是透明的。 应用程序调用序列化程序“write”方法来保存文档,而反序列化程序“read”方法访问数据存储并重新创建内存中的原始实例。 应用程序通常不关心数据存储的具体格式,只要序列化和反序列化过程能够将文档重新创建回其原始形式。
应用程序通常提供多个序列化选项,允许用户将文档保存到不同的介质或不同的格式。 例如,应用程序可能提供“另存为”选项,将文档存储到磁盘文件、数据库或 Web 服务。 同样,不同的序列化程序可以采用不同的格式存储文档,例如 HTML、RTF、XML、XPS 或替代第三方格式。 对于应用程序,序列化定义一个接口,用于隔离每个特定序列化程序的实现中存储介质的详细信息。 除了封装存储详细信息的好处外,.NET Framework System.Windows.Documents.Serialization API 还提供其他几个重要的功能。
.NET Framework 3.0 文档序列化程序的功能
直接访问高级文档对象(逻辑树和视觉对象)可以有效存储分页内容、2D/3D 元素、图像、媒体、超链接、批注和其他支持内容。
同步和异步操作。
支持具有增强功能的插件序列化程序:
可供所有 .NET Framework 应用程序使用的系统范围访问。
简单的应用插件可发现性。
自定义第三方插件的简单部署、安装和更新。
用户界面对自定义运行时设置和选项的支持。
XPS 打印路径
Microsoft .NET Framework XPS 打印路径还提供一种可扩展的机制,用于通过打印输出编写文档。 XPS 既充当文档文件格式,也是 Windows Vista 原生打印后台格式。 XPS 文档可以直接发送到与 XPS 兼容的打印机,而无需转换为中间格式。 有关打印路径输出选项和功能的其他信息,请参阅 打印概述 。
插件序列化器
System.Windows.Documents.Serialization这些 API 支持插件序列化程序和链接序列化程序,这些序列化程序与应用程序分开安装,在运行时绑定,并使用SerializerProvider发现机制进行访问。 插件序列化程序为便于部署和系统范围的使用提供了增强的优势。 可以为部分信任环境(例如XAML浏览器应用程序(XBAP))实现链接序列化程序,因为在这些环境中,插件序列化程序无法访问。 链接序列化程序基于类的 SerializerWriter 衍生实现进行编译并直接链接到应用程序。 插件序列化程序和链接序列化程序都通过相同的公共方法和事件来运行,这样就可以轻松地在同一应用程序中使用或两种类型的序列化程序。
插件序列化程序通过为新的存储设计和文件格式提供扩展性,从而帮助应用程序开发人员,而无需在生成时直接为每个潜在格式编写代码。 插件序列化程序还提供了一种标准化的方法,用于为自定义或专有文件格式部署、安装和更新系统可访问的插件,从而为第三方开发人员带来好处。
使用插件式序列化程序
插件序列化程序易于使用。 该 SerializerProvider 类为系统上安装的每个插件枚举一个 SerializerDescriptor 对象。 该 IsLoadable 属性基于当前配置筛选已安装的插件,并验证应用程序是否可以加载和使用序列化程序。 SerializerDescriptor 还提供其他属性,例如 DisplayName 以及 DefaultFileExtension,应用程序可使用DefaultFileExtension来提示用户选择序列化程序,以获取可用的输出格式。 XPS 的默认插件序列化程序随 .NET Framework 一起提供,并且始终会枚举。 用户选择输出格式后, CreateSerializerWriter 该方法用于为特定格式创建一个 SerializerWriter 。 SerializerWriter.Write然后,可以调用该方法将文档流输出到数据存储。
以下示例演示了在“PlugInFileFilter”属性中使用SerializerProvider方法的应用程序。 PlugInFileFilter 枚举已安装的插件,并生成包含可用文件选项的 SaveFileDialog筛选器字符串。
// ------------------------ PlugInFileFilter --------------------------
/// <summary>
/// Gets a filter string for installed plug-in serializers.</summary>
/// <remark>
/// PlugInFileFilter is used to set the SaveFileDialog or
/// OpenFileDialog "Filter" property when saving or opening files
/// using plug-in serializers.</remark>
private string PlugInFileFilter
{
get
{ // Create a SerializerProvider for accessing plug-in serializers.
SerializerProvider serializerProvider = new SerializerProvider();
string filter = "";
// For each loadable serializer, add its display
// name and extension to the filter string.
foreach (SerializerDescriptor serializerDescriptor in
serializerProvider.InstalledSerializers)
{
if (serializerDescriptor.IsLoadable)
{
// After the first, separate entries with a "|".
if (filter.Length > 0) filter += "|";
// Add an entry with the plug-in name and extension.
filter += serializerDescriptor.DisplayName + " (*" +
serializerDescriptor.DefaultFileExtension + ")|*" +
serializerDescriptor.DefaultFileExtension;
}
}
// Return the filter string of installed plug-in serializers.
return filter;
}
}
用户选择输出文件名后,以下示例说明如何使用 CreateSerializerWriter 该方法以指定格式存储给定文档。
// Create a SerializerProvider for accessing plug-in serializers.
SerializerProvider serializerProvider = new SerializerProvider();
// Locate the serializer that matches the fileName extension.
SerializerDescriptor selectedPlugIn = null;
foreach ( SerializerDescriptor serializerDescriptor in
serializerProvider.InstalledSerializers )
{
if ( serializerDescriptor.IsLoadable &&
fileName.EndsWith(serializerDescriptor.DefaultFileExtension) )
{ // The plug-in serializer and fileName extensions match.
selectedPlugIn = serializerDescriptor;
break; // foreach
}
}
// If a match for a plug-in serializer was found,
// use it to output and store the document.
if (selectedPlugIn != null)
{
Stream package = File.Create(fileName);
SerializerWriter serializerWriter =
serializerProvider.CreateSerializerWriter(selectedPlugIn,
package);
IDocumentPaginatorSource idoc =
flowDocument as IDocumentPaginatorSource;
serializerWriter.Write(idoc.DocumentPaginator, null);
package.Close();
return true;
}
安装插件序列器
该 SerializerProvider 类提供用于插件序列化程序发现和访问的高级应用程序接口。 SerializerProvider 找到系统上安装和可访问的序列化程序,并向应用程序提供其列表。 已安装序列化程序的具体内容通过注册表设置定义。 可以使用该方法将插件序列化程序添加到注册表 RegisterSerializer ;或者如果尚未安装 .NET Framework,插件安装脚本可以直接设置注册表值本身。 该方法 UnregisterSerializer 可用于删除以前安装的插件,也可以通过卸载脚本同样重置注册表设置。
创建插件序列化程序
插件序列化程序和链接序列化程序都使用相同的公开的公共方法和事件,同样也可以设计为同步或异步作。 通常遵循三个基本步骤来创建插件序列化程序:
首先实现和调试序列化程序作为链接序列化程序。 最初在测试应用程序中直接创建编译和链接的序列化程序可提供对断点和其他调试服务的完全访问权限,这些服务有助于测试。
完全测试序列化程序后,会添加一个 ISerializerFactory 接口来创建插件。 该 ISerializerFactory 接口允许完全访问包括逻辑树、 UIElement 对象 IDocumentPaginatorSource和 Visual 元素的所有 .NET Framework 对象。 此外, ISerializerFactory 还提供链接序列化程序使用的相同同步和异步方法和事件。 由于大型文档可能需要一些时间来输出,因此建议使用异步作来维护响应式用户交互,并在数据存储出现问题时提供“取消”选项。
创建插件序列化程序后,将实现安装脚本以分发和安装插件(并卸载)插件(请参阅上面的“安装插件序列化程序”)。