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

策略断言说明服务终结点的功能和要求。服务应用程序可以在服务元数据中使用自定义策略断言,来将终结点、绑定或协定自定义信息传递到客户端应用程序。您可以使用 Windows Communication Foundation (WCF) 根据通信的功能和要求导出终结点、操作或消息主题的 WSDL 绑定中附加的策略断言。

可以通过以下方式导出自定义策略断言:在 System.ServiceModel.Channels.BindingElement 上实现 System.ServiceModel.Description.IPolicyExportExtension 接口,然后或者将绑定元素直接插入到服务终结点的绑定,或者在应用程序配置文件中注册绑定元素。策略导出实现应将自定义策略断言作为 System.Xml.XmlElement 实例添加到传入 ExportPolicy 方法的 System.ServiceModel.Description.PolicyConversionContext 上的相应 System.ServiceModel.Description.PolicyAssertionCollection

另外,您需要检查 WsdlExporter 类的 PolicyVersion 属性,并根据指定的策略版本导出正确的命名空间中的嵌套策略表达式和策略框架属性。

若要导入自定义策略断言,请参见 System.ServiceModel.Description.IPolicyImportExtension如何:导入自定义策略断言

导出自定义策略断言

  1. System.ServiceModel.Channels.BindingElement 上实现 System.ServiceModel.Description.IPolicyExportExtension 接口。下面的代码示例演示了在绑定级别实现自定义策略断言。

    #Region "IPolicyExporter Members"
    Public Sub ExportPolicy(ByVal exporter As MetadataExporter, ByVal policyContext As PolicyConversionContext) Implements IPolicyExportExtension.ExportPolicy
      If exporter Is Nothing Then
        Throw New NullReferenceException("The MetadataExporter object passed to the ExporterBindingElement is null.")
      End If
      If policyContext Is Nothing Then
        Throw New NullReferenceException("The PolicyConversionContext object passed to the ExporterBindingElement is null.")
      End If
    
      Dim elem As XmlElement = doc.CreateElement(name1, ns1)
      elem.InnerText = "My custom text."
      Dim att As XmlAttribute = doc.CreateAttribute("MyCustomAttribute", ns1)
      att.Value = "ExampleValue"
      elem.Attributes.Append(att)
      Dim subElement As XmlElement = doc.CreateElement("MyCustomSubElement", ns1)
      subElement.InnerText = "Custom Subelement Text."
      elem.AppendChild(subElement)
      policyContext.GetBindingAssertions().Add(elem)
      Console.WriteLine("The custom policy exporter was called.")
    End Sub
    #End Region
    
    #region IPolicyExporter Members
    public void ExportPolicy(MetadataExporter exporter, PolicyConversionContext policyContext)
    {
      if (exporter == null)
        throw new NullReferenceException("The MetadataExporter object passed to the ExporterBindingElement is null.");
      if (policyContext == null)
        throw new NullReferenceException("The PolicyConversionContext object passed to the ExporterBindingElement is null.");
    
      XmlElement elem = doc.CreateElement(name1, ns1);
      elem.InnerText = "My custom text.";
      XmlAttribute att = doc.CreateAttribute("MyCustomAttribute", ns1);
      att.Value = "ExampleValue";
      elem.Attributes.Append(att);
      XmlElement subElement = doc.CreateElement("MyCustomSubElement", ns1);
      subElement.InnerText = "Custom Subelement Text.";
      elem.AppendChild(subElement);
      policyContext.GetBindingAssertions().Add(elem);
      Console.WriteLine("The custom policy exporter was called.");
    }
    #endregion
    
  2. 以编程方式或者使用应用程序配置文件将绑定元素插入到终结点绑定。请参见下面的过程。

使用应用程序配置文件插入绑定元素

  1. 为自定义策略断言绑定元素实现 System.ServiceModel.Configuration.BindingElementExtensionElement

  2. 使用 <bindingElementExtensions> 元素将绑定元素扩展添加到配置文件。

  3. 使用 System.ServiceModel.Channels.CustomBinding 生成一个自定义绑定。

以编程方式插入绑定元素

  1. 创建一个新的 System.ServiceModel.Channels.BindingElement 并将其添加到 System.ServiceModel.Channels.CustomBinding

  2. 将步骤 1 中的自定义绑定添加到一个新的终结点,并通过调用 AddServiceEndpoint 方法将该新服务终结点添加到 System.ServiceModel.ServiceHost

  3. 打开 ServiceHost。下面的代码示例演示如何创建自定义绑定以及如何以编程方式插入绑定元素。

    Dim baseAddress As New Uri("https://localhost:8000/servicemodelsamples/service")
    
    ' Create a ServiceHost for the CalculatorService type and provide the base address.
    Using serviceHost As New ServiceHost(GetType(CalculatorService), baseAddress)
        ' Create a custom binding that contains two binding elements.
        Dim reliableSession As New ReliableSessionBindingElement()
        reliableSession.Ordered = True
    
        Dim httpTransport As New HttpTransportBindingElement()
        httpTransport.AuthenticationScheme = System.Net.AuthenticationSchemes.Anonymous
        httpTransport.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard
    
        Dim binding As New CustomBinding(reliableSession, httpTransport)
    
        ' Add an endpoint using that binding.
        serviceHost.AddServiceEndpoint(GetType(ICalculator), binding, "")
    
        ' Add a MEX endpoint.
        Dim smb As New ServiceMetadataBehavior()
        smb.HttpGetEnabled = True
        smb.HttpGetUrl = New Uri("https://localhost:8001/servicemodelsamples")
        serviceHost.Description.Behaviors.Add(smb)
    
        ' Open the ServiceHostBase to create listeners and start listening for messages.
        serviceHost.Open()
    
        ' The service can now be accessed.
        Console.WriteLine("The service is ready.")
        Console.WriteLine("Press <ENTER> to terminate service.")
        Console.WriteLine()
        Console.ReadLine()
    
        ' Close the ServiceHostBase to shutdown the service.
        serviceHost.Close()
    End Using
    
    Uri baseAddress = new Uri("https://localhost:8000/servicemodelsamples/service");
    
    // Create a ServiceHost for the CalculatorService type and provide the base address.
    using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), baseAddress))
    {
        // Create a custom binding that contains two binding elements.
        ReliableSessionBindingElement reliableSession = new ReliableSessionBindingElement();
        reliableSession.Ordered = true;
    
        HttpTransportBindingElement httpTransport = new HttpTransportBindingElement();
        httpTransport.AuthenticationScheme = System.Net.AuthenticationSchemes.Anonymous;
        httpTransport.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
    
        CustomBinding binding = new CustomBinding(reliableSession, httpTransport);
    
        // Add an endpoint using that binding.
        serviceHost.AddServiceEndpoint(typeof(ICalculator), binding, "");
    
        // Add a MEX endpoint.
        ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
        smb.HttpGetEnabled = true;
        smb.HttpGetUrl = new Uri("https://localhost:8001/servicemodelsamples");
        serviceHost.Description.Behaviors.Add(smb);
    
        // Open the ServiceHostBase to create listeners and start listening for messages.
        serviceHost.Open();
    
        // The service can now be accessed.
        Console.WriteLine("The service is ready.");
        Console.WriteLine("Press <ENTER> to terminate service.");
        Console.WriteLine();
        Console.ReadLine();
    
        // Close the ServiceHostBase to shutdown the service.
        serviceHost.Close();
    }
    

另请参见

任务

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

参考

IPolicyImportExtension
IPolicyExportExtension