在流模式下利用消息头传输带外信息2010-11-27 cnblogs suyan010203WCF为传输层实现数据流在客户和服务之间进行传输提供了很好的支持,不过 在使用这种方式时,我们必须遵循相应的约定。WCF服务在启动时会首先检查操 作契约是否符合这种规范。因为通常模式下我们不能简单地在客户中使用特定的 流,如我们在传输文件时,我们目的是要得到文件对象,而不是流对象。因为我 们使用了不同类型的文件(如:*.doc,*.exe等),那么在另一端我们应该能够 重现这种类型,不过由于使用流传输带来很好的性能,于是我们想在文件传输中 使用这种流模式。那么就得附加相应的文件信息给异端,以便重现文件。这时我 们就可以使用SOAP消息头来附加这些信息了。1流模式的操作契约约定:首先我们先来了解一下使用流模式的基本的操作契约要求。要使用流模式, 我们在操作契约中只能是以单个的输入输出流作为参数,也就是说方法的参数和 返回参数,要么是Stream对象或派生类对象,要么void,形如以下的方法签名可 认可:void SendStream(Stream inStream);
Stream ReceiveStream();
Stream SendAndReceiveStream(Stream inStream);
void SendAndReceiveStream(Stream inStream,out Stream outStream) ;
void ReceiveStream(out Stream outStream)
从上面的签名我们可以看出如果我们要在服务和客户之间传递一个文件流, 在方法中是无法传递一个参数来达到的,所以这儿为了传递文件名和路径,我们 选择使用消息头附加这些信息的方式来实现,这儿定义操作契约为:[ServiceContract ]
public interface ISendStreamService
{
//利用流的传输模式来实现,消息头附加信息
[OperationContract]
void SendStream(Stream stream);
}
2 WCF消息头相关的类和方法OperationContext类代表操作上下文,它提供的IncomingMessageHeaders和 OutgoingMessageHeaders属性来操作输入输出消息头:public sealed class OperationContext :IExtensibleObject<OperationContext>{
public MessageHeaders OutgoingMessageHeaders { get; }
public MessageHeaders IncomingMessageHeaders { get; }
……
}
MessageHeader<T>代表SOAP 标头的内容,用泛型类来增强类型的安全 。public class MessageHeader<T>{
public MessageHeader();
public MessageHeader(T content);
public MessageHeader(T content, bool mustUnderstand, string actor, bool relay);
//得到与类型无关的原始消息头
public MessageHeader GetUntypedHeader(string name, string ns);
}
MessageHeaders代表消息头的消息集合,这儿我们只用到 GetHeader<T>()泛型方法public sealed class MessageHeaders : IEnumerable<MessageHeaderInfo>, IEnumerable{
public T GetHeader<T>(int index);
public T GetHeader<T>(int index, XmlObjectSerializer serializer);
public T GetHeader<T>(string name, string ns);
public T GetHeader<T>(string name, string ns, params string[] actors);
public T GetHeader<T>(string name, string ns, XmlObjectSerializer serializer);
……
}