首页 / 软件开发 / WCF / 《WCF技术内幕》23
《WCF技术内幕》232011-06-20 博客园 Frank Xu Lei译《WCF技术内幕》23:第2部分_第5章_消息:XmlDictionaryReader和回到MessageXmlDictionaryReader类型XmlDictionaryReader抽象类型继承自System.Xml.XmlReader,因此继承了很 多XmlReader的特性。和XmlReader 一样,XmlDictionaryReader定义了几个工厂 方法,他们返回的是XmlDictionaryReader的子类型的实例。更确切地说, XmlDictionaryReader包装了一个Stream,并定义了许多以Read开头的方法。因 此,由于继承的层次关系,使用 XmlDictionaryReader和XmlReader很相似。和XmlReader不同,XmlDictionaryReader的目的是为了读取序列化的和编码 过的XML Infosets ,并且可以由选择地借助XmlDictionary来实现语义压缩的反 向处理。作用上,XmlDictionaryReader 和XmlDictionaryWriter正好相反,并 且2个类型的对象模型非常相似。让我们从XmlDictionaryReader的创建方法开始 学习,然后详细研究如何使用它的Read方法。因为XmlDictionaryReader和 XmlDictionaryWriter的相似性,本节会比上一节XmlDictionaryWriter要简短一 些。创建一个XmlDictionaryReader对象XmlDictionaryReader类型定义了几个工厂方法,所有这些方法都直接或者间 接地,接受一个Stream 或Byte[]的引用。通常来说,面向stream的方法与面向 buffer的方法很相似。绝大部分,这些工厂方法都是重载一下4个方法: CreateDictionaryReader, CreateTextReader, CreateMtomReader和 CreateBinaryReader,它们的行为与XmlDictionaryWriter的相同名字工厂方法 对应。为了避免重复,我们将会关注XmlDictionaryReader的工厂方法的显著特 性上。几个工厂方法接受一个Stream的引用,这些面向stream的工厂方法使用的其 它参数包含一个XmlDictionaryQuotas 对象的引用和一个 OnXmlDictionaryReaderClose委托。在所有的情况下,前者调用后者,为 XmlDictionaryQuotas 和OnXmlDictionaryReaderClose参数传递null引用。XmlDictionaryQuotas类型是一个状态容器,它用来定义与XML反序列化相关 的重要的阀值。例如,这个类型定义反序列化中用到的节点深度的最大值、反序 列化最大的String长度、消息体的最大数组长度等等【老徐备注1】。OnXmlDictionaryReaderClose委托在XmlDictionaryReader 的Close方法几乎 结束的时候调用。当这个委托被激活以后,XmlDictionaryReader的大部分状态 被设置为null。因此,这个委托可以用来作为提醒机制(很像一个事件event) ,但不会提供XmlDictionaryReader状态相关的任何有价值的信息(除非Null是 有价值的)。Message编码器使用OnXmlDictionaryReaderClose委托去把 XmlDictionaryReader对象放到对象池。这些编码器依赖 OnXmlDictionaryReaderClose委托这样的提醒,它会返回一个资源池里的 XmlDictionaryReader实例。一下代码演示了如何实例化一个XmlDictionaryReader对象:private static void CreateTextReader() {
Console.WriteLine("==== Creating XML Dictionary Text Reader ====");
MemoryStream stream = new MemoryStream();
// create an XmlDictionaryWriter and serialize/encode some XML
XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stream,
Encoding.BigEndianUnicode, false);
writer.WriteStartDocument();
writer.WriteElementString("SongName",
"urn:ContosoRockabilia",
"Aqualung");
writer.Flush();
stream.Position = 0;
// create an XmlDictionaryReader to decode/deserialize the XML
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(
stream, Encoding.BigEndianUnicode, new XmlDictionaryReaderQuotas(),
delegate { Console.WriteLine("closing reader"); } );
reader.MoveToContent();
Console.WriteLine("Read XML Content:{0}",reader.ReadOuterXml ());
Console.WriteLine("about to call reader.Close()");
reader.Close();
Console.WriteLine("reader closed");
}