Override BaseAddress with WsdlExtensions (contrib)

Apr 7, 2010 at 7:11 PM

Background:

The "Location" property on WsdlExtensions can get a little unwieldy when managing multiple endpoints in multiple environments (becuase it requires that you create duplicate behaviors for each endpoint address).  I wanted to use a common behavior in which I could specify a single "baseAddress" and let the exporter create the relative address for me.

Feel free to add this to a future release!

Example:

<wsdlExtensions baseAddress="http://my.dns" singleFile="true" />

Changes to WsdlExtensionsConfig:

[ConfigurationProperty("baseAddress", DefaultValue = null)]
public Uri BaseAddress
{
    get
    {
        return (Uri)base["baseAddress"];
    }
    set
    {
        base["baseAddress"] = value;
    }
}

WsdlExtensions Constructor:

public Uri BaseAddress { get; set; }
...
internal WsdlExtensions(WsdlExtensionsConfig config)
{
    this.Location = config.Location;
    this.BaseAddress = config.BaseAddress;
    this.SingleFile = config.SingleFile;
}

WsdlExtensions.ExportEndpoint:

void IWsdlExportExtension.ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context)
{
    ...
    else if (BaseAddress != null)
    {
        // Create a relative uri from the baseAddress
        var relativeAddress = context.Endpoint.Address.Uri.LocalPath;
        var uri = new Uri(BaseAddress, relativeAddress);

        // Override locations with new uri
        LocationOverrideExporter.ExportEndpoint(exporter, context, uri);

        // Correct the Endpoint Address
        // note: this fixes wsa10:EndpointReference on Custom Bindings
        OverrideEndpointAddress(context);

        // Fix the SoapAddressBindings
        OverrideBinding(context);
    }
}

private void OverrideEndpointAddress(WsdlEndpointConversionContext context)
{
    var oldAddress = context.Endpoint.Address;

    // Create the new address
    var uri = new Uri(BaseAddress, oldAddress.Uri.LocalPath);
    var address = new EndpointAddress(uri, oldAddress.Headers.ToArray());

    // Assign the new address to the endpoint
    context.Endpoint.Address = address;
}

private void OverrideBinding(WsdlEndpointConversionContext context)
{
    WSDL.Port port = context.WsdlPort;

    // Fix the SoapAddressBindings
    foreach (var addressBinding in port.Extensions.OfType<WSDL.SoapAddressBinding>())
    {
        var oldUri = new Uri(addressBinding.Location);
        var newUri = new Uri(BaseAddress, oldUri.LocalPath);
        addressBinding.Location = newUri.ToString();
    }
}

done...