How to alter the WSDL generation in a ASMX service
As more and more teams are moving their applications to 2008 server,
one of the primary task includes upgrading their traditional web services (ASMX) to WCF service.
As much as important task this is - few teams may decide to go ahead with the ASMX web service itself for the time being and
decide to upgrade later on.
However the issue comes - when you deploy and see the web service is working fine (you are able to browse the service url
e.g: http://foo.abc.com/[applicationname]/[filename].asmx)
Problem
This problem that you will see in the Every standard environment is that
once you deploy your service to one of the environments the URI that comes back in the WSDL
now has a port number in it and when you try and browse to it or use a tool to generate a proxy it fails (due to security reasons on the network).
It's a strong recommendation to upgrade your ASMX to WCF due to it's clear benefits that you may already know. An additional specific thing that you may or may not know is that the above issue could be easily handled by just making a small change in the service configuration in the web.config file if using WCF. And here is an excellent article on how and what precisely you need to do. It may take some time depending on the service conplexity but its worth it.
Fix
However if you decide not to and want to continue with the ASMX service itself due to some reason
then below is the explanation on how to tackle the invalid Uri in the ASMX WSDL document.
The way you can control the load balancer mess is by injecting the WSDL request and replacing
inaccessible Uri with the correct Uri in the WSDL document.
This could be done via inheriting the SoapExtensionReflector class from System.Web.Services.Description.
Create a class like this -
Imports System
Imports System.Text.Regular.Expressions
Imports System.Web.Services.Description
Public Class LoadBalancerPortMessFix
Inherits SoapExtensionReflector
Public Overrides Sub ReflectMethod()
'Do Nothing
End Sub
Public Overrides Sub ReflectDescription()
Dim Description As ServiceDescription= ReflectionContect.ServiceDescription
For Each Service as Service In description.Services
For Each port as POrt in Service.Ports
For each Extenstion AS ServiceDescriptionFormatExtension In POrt.Extensions
Dim Soapbinding as SoapAddressBinding= DirectCast(extension,SoapAddressBinding)
If not Soapbinding Is Nothing Then
'User Appropriate Logic Here
soapbinding.Loacation=Regex.Replace(Soapbinding.Location, ":[0-9]+", String.Empty)
End If
Next
Next
Next
End Sub
End Class
You can also Control Http|Https if needed.
And then configure this class to allow intercept the WSDL generation
<webservices>
<soapExtensionReflectorTypes>
'Fully Qualified Name of the Class
<add type="MyProject.MyApplication.web.PortMessFix, MyApplication" />
</soapExtensionReflectorTypes>
</webservices>
After doing that we can see that the WSDL now generates with the replaced URI and
we are able to both browse it and use tools to generate proxies against it.
-<wsdl:service name="Students">
-<wsdl:port name="StudentsSoap" binding ="tns:StudentsSoap">
<soap:address location="http://xyzservice.abc.com/studentservice.asmx"/>
</wsdl:port>
-<wsdl:port name="StudentsSoap2" binding ="tns:StudentsSoap2">
<soap:address location="http://xyzservice.abc.com/studentservice.asmx"/>
</wsdl:port>
</wsdl:service>