3

We have some old ASMX web services which have been moved behind extra layers of security. The WSDL is autogenerated runtime and is now using the IP of the server it's running on, instead of the public DNS. How do you change the IP with the public DNS via code or web.config?

The web service offers both SOAP via HTTP POST/GET with query strings and the more common scenario, SOAP via HTTP POST with SOAP-request-body. I want to switch the local IP with the public DNS name of the run-time generated WSDL. I have succeeded in doing so in the common scenario, using SoapExtensionReflector, but it doesn't work for the WSDL ports using query strings.

A simplified version of the SoapExtensionReflector looks like this:

public class MySoapExtensionReflector : SoapExtensionReflector
{
    public override void ReflectDescription()
    {
        var description = ReflectionContext.ServiceDescription;

        foreach (Service service in description.Services)
        {
            foreach (Port port in service.Ports)
            {
                foreach (ServiceDescriptionFormatExtension extension in port.Extensions)
                {
                    SoapAddressBinding binding = extension as SoapAddressBinding;
                    if (null != binding)
                    {
                        binding.Location = Regex.Replace(binding.Location,
                                           "http://localhost:2017", 
                                           "https://example.com");
                    }
                }
            }
        }
    }

    public override void ReflectMethod()
    {
        // No implementation
    }
}

The relevant parts of the web.config:

<system.web>
    <webServices>
      <soapExtensionReflectorTypes>
        <add type="MyService.MySoapExtensionReflector, MyService"/>
      </soapExtensionReflectorTypes>
      <protocols>
        <add name="HttpGet"/>
        <add name="HttpPost"/>
      </protocols>
    </webServices>
</system.web>

This yields the following the result in the WSDL:

<wsdl:service name="MyService">
    <wsdl:port name="MyServiceSoap" binding="tns:MyServiceSoap">
        <soap:address location="https://example.com/Myservice.asmx"/>
    </wsdl:port>
    <wsdl:port name="MyServiceSoap12" binding="tns:MyServiceSoap12">
        <soap12:address location="https://example.com/Myservice.asmx"/>
    </wsdl:port>
    <wsdl:port name="MyServiceHttpGet" binding="tns:MyServiceHttpGet">
        <http:address location="http://localhost:2017/Myservice.asmx"/>
    </wsdl:port>
    <wsdl:port name="MyServiceHttpPost" binding="tns:MyServiceHttpPost">
        <http:address location="http://localhost:2017/Myservice.asmx"/>
    </wsdl:port>
</wsdl:service>

Which is not quite the desired result. The two last ports are generated by the protocol - HttpPost and HttpGet definition in the web.config.

How do you change this, so the WSDL-ports have the desired hostname?

The result should look like this:

<wsdl:service name="MyService">
    <wsdl:port name="MyServiceSoap" binding="tns:MyServiceSoap">
        <soap:address location="https://example.com/Myservice.asmx"/>
    </wsdl:port>
    <wsdl:port name="MyServiceSoap12" binding="tns:MyServiceSoap12">
        <soap12:address location="https://example.com/Myservice.asmx"/>
    </wsdl:port>
    <wsdl:port name="MyServiceHttpGet" binding="tns:MyServiceHttpGet">
        <http:address location="http://example.com/Myservice.asmx"/>
    </wsdl:port>
    <wsdl:port name="MyServiceHttpPost" binding="tns:MyServiceHttpPost">
        <http:address location="http://example.com/Myservice.asmx"/>
    </wsdl:port>
</wsdl:service>
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459

0 Answers0