.Net does a nice job of sensing the underlying protocol when generating WSDL. For instance, if I run a service as "myService" on SSL, the underlying WSDL is wired to contain the <soap:address> location mapped to "https://..." instead of "http://..." However there are times when this sensing is not enough. A good relational setup between your load-balancer/encryptor setup should limit the change need to http->https, but this implementation also offers other flexibility as well. I just can't think of a good use-case right now.
When running with a front-end encryption appliance for offloading the cpu cost of SSL, the webservers themselves typically run on the http/port 80/non-encrypted protocol. Since .Net senses this, the WSDL is generated with "http://" prefixes in the soap:address which is incorrect for consumers of the service.
Handling this took a bunch of digging and feels extremely hack-ish. But it's a necessity in this scenario. To accomplish this task take the following steps:
-
Derive a class from SoapExtensionReflector that overrides the ReflectMethod().
-
Handle the remapping in the ReflectMethod() of the class created above.
-
Reference your new class under the webServices/soapExtensionReflectorTypes in web.config.
Here is a sample of the derived class:
public class SoapAddressReflector : SoapExtensionReflector
{
public override void ReflectMethod()
{
ServiceDescription sd = ReflectionContext.ServiceDescription;
foreach (Service service in sd.Services)
{
foreach( Port port in service.Ports)
{
foreach (ServiceDescriptionFormatExtension extension in port.Extensions)
{
SoapAddressBinding address = (SoapAddressBinding)extension;
address.Location = RemapHttpReferencesToHttps(address.Location);
}
}
}
}
private string RemapHttpReferencesToHttps( string location )
{
return location.Replace("http:", "https:");
}
}
}
Here is the code to add to the web.config file:
<webServices>
<soapExtensionReflectorTypes>
<add type="Reuters.DataScopeSelect.Web.Api.SoapAddressReflector, Reuters.DataScopeSelect.Web.Api"/>
</soapExtensionReflectorTypes>
</webServices>
For a bogus webservice named "myService" running server-native on http, the modified wsdl appears as follows:
- <wsdl:service name="myService">
- <wsdl:port name="myServiceSoap" binding="tns:ExtractionServiceSoap">
- <wsdl:port name="myServiceSoap12" binding="tns:myServiceSoap12">
</wsdl:service>
</wsdl:definitions>