《WCF技术剖析(卷1)》自出版近20天以来,得到了园子里的朋友和广大WCF爱好者的一致好评,并被卓越网计算机书店作为首页推荐,在这里对大家的支持表示感谢。同时我将一直坚持这个博文系列,与大家分享我对WCF一些感悟和学习经验。在《消息(Message)详解》系列的上篇和中篇,先后对消息版本、详细创建、状态机和基于消息的基本操作(读取、写入、拷贝、关闭)进行了深入剖析,接下来我们来谈谈消息的另一个重要组成部分:消息报头(Message Header)。
按照SOAP1.1或者SOAP1.2规范,一个SOAP消息由若干SOAP报头和一个SOAP主体构成,SOAP主体是SOAP消息的有效负载,一个SOAP消息必须包含一个唯一的消息主体。SOAP报头是可选的,一个SOAP消息可以包含一个或者多个SOAP报头,SOAP报头一般用于承载一些控制信息。消息一经创建,其主体内容不能改变,而SOAP报头则可以自由地添加、修改和删除。正是因为SOAP的这种具有高度可扩展的设计,使得SOAP成为实现SOA的首选(有这么一种说法SOAP= SOA Protocol)。
按照SOAP 1.2规范,一个SOAP报头集合由一系列XML元素组成,每一个报头元素的名称为Header,命名空间为http://www.w3.org/2003/05/soap-envelope。每一个报头元素可以包含任意的属性(Attribute)和子元素。在WCF中,定义了一系列类型用于表示SOAP报头。
一、MessageHeaders、MessageHeaderInfo、MessageHeader和MessageHeader<T>
在Message类中,消息报头集合通过只读属性Headers表示,类型为System.ServiceModel.Channels.MessageHeaders。MessageHeaders本质上就是一个System.ServiceModel.Channels.MessageHeaderInfo集合。
1: public abstract class Message : IDisposable 2: { 3: //其他成员 4: public abstract MessageHeaders Headers { get; } 5: } 1: public sealed class MessageHeaders : IEnumerable<MessageHeaderInfo>, IEnumerable 2: { 3: //省略成员 4: }
MessageHeaderInfo是一个抽象类型,是所有消息报头的基类,定义了一系列消息SOAP报头的基本属性。其中Name和Namespace分别表示报头的名称和命名空间,Actor、MustUnderstand、Reply与SOAP 1.1或者SOAP 1.2规定SOAP报头同名属性对应。需要对SOAP规范进行深入了解的读者可以从W3C官方网站下载相关文档。
1: public abstract class MessageHeaderInfo 2: { 3: protected MessageHeaderInfo(); 4: 5: public abstract string Actor { get; } 6: public abstract bool IsReferenceParameter { get; } 7: public abstract bool MustUnderstand { get; } 8: public abstract string Name { get; } 9: public abstract string Namespace { get; } 10: public abstract bool Relay { get; } 11: }
当我们针对消息报头编程的时候,使用到的是另一个继承自MessageHeaderInfo的抽象类:System.ServiceModel.Channels.MessageHeader。除了实现MessageHeaderInfo定义的抽象只读属性外,MessageHeader中定义了一系列工厂方法(CreateHeader)方便开发人员创建MessageHeader对象。这些CreateHeader方法接受一个可序列化的对象,并以此作为消息报头的内容,WCF内部会负责从对象到XML InfoSet的序列化工作。此外,可以通过相应的WriteHeader方法对MessageHeader对象执行写操作。MessageHeader定义如下:
1: public abstract class MessageHeader : MessageHeaderInfo 2: { 3: public static MessageHeader CreateHeader(string name, string ns, object value); 4: public static MessageHeader CreateHeader(string name, string ns, object value, bool mustUnderstand); 5: //其他CreateHeader方法 6: 7: public void WriteHeader(XmlDictionaryWriter writer, MessageVersion messageVersion); 8: public void WriteHeader(XmlWriter writer, MessageVersion messageVersion); 9: //其他WriteHeader方法 10: 11: public override string Actor { get; } 12: public override bool IsReferenceParameter { get; } 13: public override bool MustUnderstand { get; } 14: public override bool Relay { get; } 15: }
除了MessageHeader,WCF还提供一个非常有价值的泛型类:System.ServiceModel. MessageHeader<T>,泛型参数T表示报头内容对应的类型,MessageHeader<T>为我们提供了强类型的报头创建方式。由于Message的Headers属性是一个MessageHeaderInfo的集合,MessageHeader<T>并不能直接作为Message对象的消息报头。GetUntypedHeader方法提供了从MessageHeader<T>对象到MessageHeader对象的转换。MessageHeader<T>定义如下:
1: public class MessageHeader<T> 2: { 3: public MessageHeader(); 4: public MessageHeader(T content); 5: public MessageHeader(T content, bool mustUnderstand, string actor, bool relay); 6: public MessageHeader GetUntypedHeader(string name, string ns); 7: 8: public string Actor { get; set; } 9: public T Content { get; set; } 10: public bool MustUnderstand { get; set; } 11: public bool Relay { get; set; } 12: }
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索string
, soap
, 消息
, public
, abstract
一个
,以便于您获取更多的相关知识。