如何:导人自定义策略断言

策略断言说明服务终结点的功能和要求。 客户端应用程序可以在服务元数据中使用策略断言来配置客户端绑定或自定义服务终结点的服务协定。

自定义策略断言可通过实现 System.ServiceModel.Description.IPolicyImportExtension 接口并将该对象传递给元数据系统或通过在应用程序配置文件中注册实现类型来导入。 IPolicyImportExtension 接口的实现必须提供无参数构造函数。

导入自定义策略断言

  1. 在类上实现 System.ServiceModel.Description.IPolicyImportExtension 接口。 请参见下面的过程。

  2. 通过以下方式之一插入自定义策略导入程序:

  3. 使用配置文件。 请参见下面的过程。

  4. 将配置文件与 ServiceModel 元数据实用工具 (Svcutil.exe) 一起使用。 请参见下面的过程。

  5. 以编程方式插入策略导入程序。 请参见下面的过程。

在任何类上实现 System.ServiceModel.Description.IPolicyImportExtension 接口

  1. IPolicyImportExtension.ImportPolicy 方法中,对于感兴趣的每个策略主题,通过在传递给该方法的 System.ServiceModel.Description.PolicyConversionContext 对象上调用相应方法(具体取决于所需的断言范围),查找要导入的策略断言。 下面的代码示例演示如何使用 PolicyAssertionCollection.Remove 方法定位自定义策略断言并在一个步骤中将该断言从集合中删除。 如果使用删除方法定位并删除断言,则不必执行步骤 4。

    // Locate the custom assertion and remove it.
    XmlElement customAssertion = context.GetBindingAssertions().Remove(name1, ns1);
    if (customAssertion != null)
    {
      Console.WriteLine(
        "Removed our custom assertion from the imported "
        + "assertions collection and inserting our custom binding element."
      );
      // Here we would add the binding modification that implemented the policy.
      // This sample does not do this.
      Console.ForegroundColor = ConsoleColor.Red;
      Console.WriteLine(customAssertion.NamespaceURI + " : " + customAssertion.Name);
      Console.WriteLine(customAssertion.OuterXml);
      Console.ForegroundColor = ConsoleColor.Gray;
    }
    
    ' Locate the custom assertion and remove it.
    Dim customAssertion As XmlElement = context.GetBindingAssertions().Remove(name1, ns1)
    If customAssertion IsNot Nothing Then
        Console.WriteLine("Removed our custom assertion from the imported " & "assertions collection and inserting our custom binding element.")
        ' Here we would add the binding modification that implemented the policy.
        ' This sample does not do this.
        Console.ForegroundColor = ConsoleColor.Red
        Console.WriteLine(customAssertion.NamespaceURI & " : " & customAssertion.Name)
        Console.WriteLine(customAssertion.OuterXml)
        Console.ForegroundColor = ConsoleColor.Gray
    End If
    
  2. 处理策略断言。 请注意,策略系统不会标准化嵌入的策略和 wsp:optional。 您必须在策略导入扩展实现中处理这些结构。

  3. 对支持策略断言指定的功能或需求的绑定或协定执行自定义。 断言通常指示绑定需要特定配置或特定绑定元素。 可以通过访问 PolicyConversionContext.BindingElements 属性来进行这些修改。 其他断言需要您修改协定。 可以使用 PolicyConversionContext.Contract 属性来访问并修改该协定。 请注意,对于同一个绑定和协定,可能会多次调用策略导入程序,但导入的是不同的替代策略(如果一个替代策略导入失败)。 你的代码应该能够处理这一行为。

  4. 从断言集合中删除自定义策略断言。 如果不删除该断言,Windows Communication Foundation (WCF) 将假定策略导入失败,并将不导入相关绑定。 如果您使用 PolicyAssertionCollection.Remove 方法定位自定义策略断言并在一个步骤中将该断言从集合中删除,则不必执行此步骤。

使用配置文件将自定义策略导入程序插入到元数据系统

  1. 将导入程序类型添加到客户端配置文件的 <policyImporters> 元素内的 <extensions> 元素。

    <client>
        <endpoint 
          address="http://localhost:8080/StatefulService" 
          binding="wsHttpBinding"
          bindingConfiguration="CustomBinding_IStatefulService" 
          contract="IStatefulService"
          name="CustomBinding_IStatefulService" />
      <metadata>
        <policyImporters>
          <extension type="Microsoft.WCF.Documentation.CustomPolicyImporter, PolicyExtensions"/>
        </policyImporters>
      </metadata>
    </client>
    
  2. 在客户端应用程序中,使用 System.ServiceModel.Description.MetadataResolverSystem.ServiceModel.Description.WsdlImporter 解析元数据,这会自动调用导入程序。

    // Download all metadata.
    ServiceEndpointCollection endpoints
      = MetadataResolver.Resolve(
        typeof(IStatefulService),
        new EndpointAddress("http://localhost:8080/StatefulService/mex")
      );
    
    ' Download all metadata. 
    Dim endpoints As ServiceEndpointCollection = MetadataResolver.Resolve(GetType(IStatefulService), New EndpointAddress("http://localhost:8080/StatefulService/mex"))
    

使用 Svcutil.exe 将自定义策略导入程序插入到元数据系统

  1. 将导入程序类型添加到 Svcutil.exe.config 配置文件的 <policyImporters> 元素内的 <extensions> 元素。 也可以通过使用 /svcutilConfig 选项指示 Svcutil.exe 加载在其他配置文件中注册的策略导入程序类型。

  2. 使用 ServiceModel 元数据实用工具 (Svcutil.exe) 导入元数据,并自动调用导入程序。

以编程方式将自定义策略导入程序插入到元数据系统

  1. 导入元数据之前,将导入程序添加到 MetadataImporter.PolicyImportExtensions 属性(例如,如果您使用的是 System.ServiceModel.Description.WsdlImporter)。

请参阅