演练:使用 SOAP 扩展更改 SOAP 消息

本主题专门介绍一项旧有技术。现在应通过使用以下链接来创建 XML Web 服务和 XML Web 服务客户端: Windows Communication Foundation.

通过将 SOAP 扩展插入到 .NET Framework SOAP 消息处理管道中,可以在 Web 服务或客户端上修改或检查正被序列化或反序列化的 SOAP 请求或响应消息。本主题将分步演示如何生成并运行 SOAP 扩展。有关 SOAP 扩展的工作原理示意图以及 SOAP 扩展方法在消息处理管道中的调用顺序,请参见使用 SOAP 扩展修改 SOAP 消息

通过此演练,您将学会如何执行以下任务:

  • SoapExtension 派生一个类。

  • 保存对 Stream 对象的引用,这些对象表示 SOAP 扩展完成处理前后的未来 SOAP 消息。

  • 初始化 SOAP 扩展特定的数据。

  • 在适当的 SoapMessageStage 或阶段中处理 SOAP 消息。

将 SOAP 扩展配置为与特定的 Web 服务方法一起运行。

必备条件

SoapExtension 派生一个类。

SoapExtension 派生的类就是执行 SOAP 扩展的功能的类。这就是说,如果 SOAP 扩展是一个加密 SOAP 扩展,则从 SoapExtension 类派生的类将执行加密和相应的解密操作。

保存对表示未来 SOAP 消息的流对象的引用

若要修改 SOAP 消息,需要获取对可用于获取未来 SOAP 消息内容的流的引用。获取此引用的唯一机会是重写 ChainStream 方法。

保存对表示未来 SOAP 消息的流对象的引用

  1. 重写 ChainStream 方法。

    ChainStream 方法具有以下签名:

    public virtual Stream ChainStream(Stream stream)
    
    Public Overridable Function ChainStream(ByVal stream As Stream) As Stream
    
  2. ChainStream 实现内,分配以参数形式传递的 Stream 实例。

    随即将向 ChainStream 传入对 Stream 的引用(在所有 SoapMessageStage 之前)。当具有较低优先级的 SOAP 扩展执行并更改 SOAP 消息后,此 Stream 将引用该 SOAP 消息的 XML(有关 SOAP 扩展优先级的详细信息,请参见“将 SOAP 扩展配置为与 Web 服务方法一起运行”)。SOAP 扩展应将此引用分配给成员变量,以供以后在 SoapMessageStage 期间(此时 SOAP 扩展将检查或修改 SOAP 消息)进行访问。

    但是,传入 ChainStreamStream 并非 SOAP 扩展应修改的 Stream

  3. ChainStream 实现内,实例化一个新的 Stream,将对该流的引用保存在私有成员变量中,然后返回该引用。

    下面的示例演示 ChainStream 方法的常规实现。

有关 ChainStream 方法的常规实现的示例,请参见如何:实现 ChainStream 方法以保存对流对象的引用

初始化 SOAP 扩展特定的数据

SoapExtension 派生的类具有两个数据初始化方法:GetInitializerInitialize

ASP.NET 基础结构调用 GetInitializer 方法的时间以及传递给该方法的参数取决于 SOAP 扩展的配置方式。(请参见“使用 SOAP 扩展修改 SOAP 消息”和“将 SOAP 扩展配置为与 Web 服务方法一起运行”。)

在使用特性配置 SOAP 扩展时初始化数据

  1. 使用以下签名实现 GetInitializer 方法:

    public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
    
    Public Overloads Overrides Function GetInitializer(methodInfo As _
       LogicalMethodInfo, attribute As SoapExtensionAttribute) As Object
    

    LogicalMethodInfo 提供的原型详细介绍了该 Web 服务方法,例如参数的数目及其数据类型。

  2. 如有必要,可调用 Initialize 方法并传递由 GetInitializer 返回的对象。对于很多 SoapExtension 实现,都可以将 Initialize 方法保留为空。

在配置文件中配置 SOAP 扩展时初始化数据

  1. 使用以下签名实现 GetInitializer 方法:

    public override object GetInitializer(Type WebServiceType)
    
    Public Overloads Overrides Function GetInitializer(WebServiceType As Type) As Object
    

    Type 参数的类型与实现该 Web 服务的类同属一类。

  2. 如有必要,可调用 Initialize 方法并传递由 GetInitializer 返回的对象。对于很多 SoapExtension 实现,都可以将 Initialize 方法保留为空。

有关如何在配置 SOAP 扩展时初始化缓存数据的示例,请参见如何:在配置 SOAP 扩展时初始化缓存数据

处理 SOAP 消息

在从 SoapExtension 派生的类中,实现的核心部分是 ProcessMessage 方法。在 SoapMessageStage 枚举中定义的每个阶段中,ASP.NET 都会多次调用此方法。

处理 SOAP 消息

  • 实现抽象 ProcessMessage 方法。

    ProcessMessage 方法的以下实现可跟踪对 Web 服务的调用。在跟踪过程中,如果 SoapMessageStage 指示已经将参数序列化为 XML,则会将该 XML 写入一个文件。

    public override void ProcessMessage(SoapMessage message) 
    {
       switch (message.Stage) 
       {
       case SoapMessageStage.BeforeSerialize:
           break;
       case SoapMessageStage.AfterSerialize:
           // Write the SOAP message out to a file.
           WriteOutput( message );
           break;
       case SoapMessageStage.BeforeDeserialize:
           // Write the SOAP message out to a file.
           WriteInput( message );
           break;
       case SoapMessageStage.AfterDeserialize:
           break;
       default:
           throw new Exception("invalid stage");
       }
    }
    
    Public Overrides Sub ProcessMessage(message As SoapMessage)
        Select Case message.Stage
          Case SoapMessageStage.BeforeSerialize
          Case SoapMessageStage.AfterSerialize
            ' Write the SOAP message out to a file.
            WriteOutput(message)
          Case SoapMessageStage.BeforeDeserialize
            ' Write the SOAP messae out to a file.
            WriteInput(message)
          Case SoapMessageStage.AfterDeserialize
          Case Else
            Throw New Exception("invalid stage")
        End Select
    End Sub
    

将 SOAP 扩展配置为与 Web 服务方法一起运行

SOAP 扩展的运行方式可通过使用自定义特性或修改配置文件加以配置。自定义特性适用于 Web 服务方法。使用配置文件时,SOAP 扩展将与配置文件范围内的所有 Web 服务一起运行。有关配置文件如何工作的详细信息,请参见Configuring Applications

使用自定义特性配置 SOAP 扩展

  1. SoapExtensionAttribute 派生一个类。

  2. 实现 SoapExtensionAttribute: ExtensionTypePriority 的两个属性。SOAP 扩展应会在 ExtensionType 属性中返回 SOAP 扩展的类型。Priority 属性表示 SOAP 扩展的相对优先级,有关信息,请参见“使用 SOAP 扩展修改 SOAP 消息”中的“应用优先级组”。

  3. 向想让 SOAP 扩展与之一起运行的每个 Web 服务方法应用该自定义特性。

在配置文件中配置 SOAP 扩展

  1. soapExtensionTypes XML 元素添加到相应 App.config 或 Web.config 文件的 webServices 部分中(如果该元素尚不存在)。

  2. soapExtensionTypes XML 元素内,为要与配置文件范围内的每项 Web 服务一起运行的每个 SOAP 扩展添加一个 add XML 元素。

    add XML 元素具有下列属性:

    • type:指定 SOAP 扩展的类型及其所在的程序集。

    • priority:指定 SOAP 扩展在其组中的相对优先级。

    • group:指定 SOAP 扩展所属的组。

另请参见

任务

如何:实现 SOAP 扩展
如何:在配置 SOAP 扩展时初始化缓存数据
如何:实现 ChainStream 方法以保存对流对象的引用

参考

SoapExtension
SoapExtensionAttribute
SoapMessageStage
LogicalMethodInfo

概念

使用 SOAP 扩展修改 SOAP 消息
XML Web services 生存期分析
生成 XML Web services 客户端

其他资源

Configuring Applications