使用 SoapContext 与过滤器通信
输出过滤器通过 Microsoft.Web.Services.SoapContext 类来管理。每个 SoapContext 对象使用简单的对象模型来记录特定的协议选项,例如是否存在用户名标记或数字证书、创建和过期时间戳、路由路径等。SoapEnvelope 类具有 Context 属性,该属性是 SoapContext 类的一个实例。当 SoapEnvelope 由输出过滤器处理时,是由 SoapContext 对象中的数据来告诉输出过滤器进行什么操作。
例如,TimestampOutputFilter 实际通过检查 SoapEnvelope 的 SoapContext 对象的属性(尤其是 SoapEnvelope.Context.Timestamps.Ttl)来设置消息的过期时间。如果您希望将消息的过期时间设置为 10 分钟,只需要按照如下所示设置该值:
// 创建封装 SoapEnvelope env = new SoapEnvelope(); ... // 以毫秒为单位,将过期时间设置为 10 分钟 env.Context.Timestamps.Ttl = 600000; |
WSE 输入过滤器也依赖于 SoapContext 类,但是其用途不同。当输入过滤器处理 SoapEnvelope 对象时,会更新它的 SoapContext 对象,以反映封装包含的协议标头。例如,TimestampInputFilter 处理消息之后,SoapEnvelope.Context.Timestamps.Created 属性会反映消息的创建时间。
在管道中使用多个过滤器
前面展示的时间戳输入和输出过滤器仅仅是 WSE 所带的 10 种内置过滤器中的两种。表 1 列出了所有内置过滤器,包括它们所在的命名空间、输入和输出过滤器类型名以及简单的功能描述。
表 1:Web Services Enhancements 中的 WSE 内置过滤器
| 命名空间 |
输入过滤器 |
输出过滤器 |
用途 |
| Microsoft.Web.Services.Diagnostics |
TraceInputFilter |
TraceOutputFilter |
向日志文件写入信息,以帮助调试 |
| Microsoft.Web.Services.Security |
SecurityInputFilter |
SecurityOutputFilter |
身份验证、签名和加密支持 (WS-Security(英文)) |
| Microsoft.Web.Services.Timestamp |
TimestampInputFilter |
TimestampOutputFilter |
时间戳支持 (WS-Security(英文)) |
| Microsoft.Web.Services.Referral |
ReferralInputFilter |
ReferralOutputFilter |
动态更新路由路径 (WS-Referral(英文)) |
| Microsoft.Web.Services.Routing |
RoutingInputFilter |
RoutingOutputFilter |
消息路由 (WS-Routing(英文)) |
表 1 中最右边的列清楚地说明了每对 WSE 过滤器的功能。一般来说,您可能希望将多个输入或输出过滤器结合起来,应用到给定的 SOAP 消息 en masse。为此,WSE 提供了 Microsoft.Web.Services.Pipeline 类,它的定义如下。
|
public class Pipeline { public Pipeline(); public Pipeline(Pipeline p); public Pipeline(SoapInputFilterCollection inputFilters, SoapOutputFilterCollection outputFilters);
public SoapInputFilterCollection inputFilters { get; } public SoapOutputFilterCollection outputFilters { get; }
public void ProcessInputMessage(SoapEnvelope envelope); public void ProcessOutputMessage(SoapEnvelope envelope); } |
每个 Pipeline 对象封装一个输入过滤器集合和一个输出过滤器集合,它们分别由 Microsoft.Web.Services.SoapInputFilterCollection 和 Microsoft.Web.Services.SoapOutputFilterCollection 类的实例来表示。这些集合通过构造函数进行初始化,并作为属性提供。Pipeline.ProcessInputMessage 和 Pipeline.ProcessOutputMessage 方法在相应的过滤器集合中进行简单的迭代,依次传递提供的 SoapEnvelope 对象。
下面是一个使用 Pipeline 类的简单程序,它使用多个输出过滤器来处理消息。特别是使用了 WSE 中内置的 TraceOutputFilter 和 TimestampOutputFilter 类。
|
static void Main(string[] args) { // 创建输入过滤器集合 SoapInputFilterCollection inputFilters = new SoapInputFilterCollection();
// 创建输出过滤器集合 SoapOutputFilterCollection outputFilters = new SoapOutputFilterCollection();
// 添加所需的输出过滤器 outputFilters.Add(new TraceOutputFilter()); outputFilters.Add(new TimestampOutputFilter());
// 创建空白的 SOAP 消息 SoapEnvelope env = new SoapEnvelope(); XmlElement body = env.CreateBody(); env.Envelope.AppendChild(body);
// 打印原始消息 Console.WriteLine("原始消息:\n\n{0}\n", env.OuterXml);
// 创建管道,封装过滤器集合 Pipeline pipe = new Pipeline(inputFilters, outputFilters);
// 使用管道的集合中的所有输出过滤器 // 处理消息 pipe.ProcessOutputMessage(env);
// 打印输出过滤后的消息 Console.WriteLine("输出过滤后的消息:\n\n{0}\n", env.OuterXml); } |
此应用程序首先创建一个空的 SoapInputFilterCollection 对象。然后创建一个 SoapOutputFilterCollection 对象,并向其添加一个 TraceOutputFilter 对象和一个 TimestampOutputFilter 对象。接着使用这两个集合来初始化一个新的 Pipeline 对象。然后使用 Pipeline 来处理空的 SoapEnvelope。程序的输出结果如下。
原始消息:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body/> </soap:Envelope> |
输出过滤后的消息:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header> <wsu:Timestamp xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility"> <wsu:Created>2002-11-14T23:17:48Z</wsu:Created> <wsu:Expires>2002-11-14T23:22:48Z</wsu:Expires> </wsu:Timestamp> </soap:Header> <soap:Body /> </soap:Envelope> |