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

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

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

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

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

导出自定义策略断言

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

    #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
    
    #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
    
  2. 以编程方式或者使用应用程序配置文件将绑定元素插入到终结点绑定。 请参见下面的过程。

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

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

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

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

以编程方式插入绑定元素

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

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

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

    Uri baseAddress = new Uri("http://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("http://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();
    }
    
    Dim baseAddress As New Uri("http://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("http://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
    

另请参阅