How to: Import Custom Policy Assertions

Policy assertions describe the capabilities and requirements of a service endpoint. Client applications can use policy assertions in service metadata to configure the client binding or to customize the service contract for a service endpoint.

Custom policy assertions are imported by implementing the System.ServiceModel.Description.IPolicyImportExtension interface and passing that object to the metadata system or by registering the implementation type in your application configuration file. Implementations of the IPolicyImportExtension interface must provide a default constructor.

To import custom policy assertions

  1. Implement the System.ServiceModel.Description.IPolicyImportExtension interface on a class. See the following procedures.

  2. Insert the custom policy importer either by:

  3. Using a configuration file. See the following procedures.

  4. Using a configuration file with ServiceModel Metadata Utility Tool (Svcutil.exe). See the following procedures.

  5. Programmatically inserting the policy importer. See the following procedures.

To implement the System.ServiceModel.Description.IPolicyImportExtension interface on any class

  1. In the System.ServiceModel.Description.IPolicyImportExtension.ImportPolicy method, for each policy subject that you are interested in, find the policy assertions that you want to import by calling the appropriate method (depending upon the scope of the assertion that you want) on the System.ServiceModel.Description.PolicyConversionContext object passed to the method. The following code example shows how to use the System.ServiceModel.Description.PolicyAssertionCollection.Remove method to locate the custom policy assertion and remove it from the collection in one step. If you use the remove method to locate and remove the assertion, you do not have to perform step 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. Process the policy assertions. Note that the policy system does not normalize nested policies and wsp:optional. You must process these constructs in your policy import extension implementation.

  3. Perform the customization to the binding or contract that supports the capability or requirement specified by the policy assertion. Typically assertions indicate that a binding requires a particular configuration or a specific binding element. Make these modifications by accessing the System.ServiceModel.Description.PolicyConversionContext.BindingElements property. Other assertions require that you modify the contract. You can access and modify the contract using the System.ServiceModel.Description.PolicyConversionContext.Contract property. Note that your policy importer may get called multiple times for the same binding and contract, but different policy alternatives if importing a policy alternative fails. Your code should be resilient to this behavior.

  4. Remove the custom policy assertion from the assertion collection. If you do not remove the assertion Windows Communication Foundation (WCF) assumes that the policy import was unsuccessful and does not import the associated binding. If you used the System.ServiceModel.Description.PolicyAssertionCollection.Remove method to locate the custom policy assertion and remove it from the collection in one step you do not have to perform this step.

To insert the custom policy importer into the metadata System using a configuration file

  1. Add the importer type to the <extensions> element inside the <policyImporters> element in the client configuration file.

    <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. In the client application, use the System.ServiceModel.Description.MetadataResolver or System.ServiceModel.Description.WsdlImporter to resolve the metadata and the importer is invoked automatically.

    // 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"))
    

To insert the custom policy importer into the metadata system using Svcutil.exe

  1. Add the importer type to the <extensions> element inside the <policyImporters> element in the Svcutil.exe.config configuration file. You can also point Svcutil.exe to load policy importer types registered in a different configuration file by using the /svcutilConfig option.

  2. Use ServiceModel Metadata Utility Tool (Svcutil.exe) to import the metadata and the importer is invoked automatically.

To insert the custom policy importer into the metadata system programmatically

  1. Add the importer to the System.ServiceModel.Description.MetadataImporter.PolicyImportExtensions property (for example, if you are using the System.ServiceModel.Description.WsdlImporter) prior to importing the metadata.

See Also

System.ServiceModel.Description.MetadataResolver
System.ServiceModel.Description.WsdlImporter
System.ServiceModel.Description.MetadataResolver
Extending the Metadata System