I am trying to access an old ASMX webservice using WCF by calling the ChannelFactory.CreateChannel()
method.
If the web service is created by WCF, everything is straightforward. I can instantiate the proxy client generated by the svcutil tool, or manually call the ChannelFactory.CreateChannel()
method. Afterwards, I can call the web service methods the same way for both scenarios.
But if the web service is of the old ASMX variety, I can still instantiate the proxy either way, but I am unable to call the same web service method.
For example, assume this basic WCF web service interface:
[ServiceContract]
public interface IWebService
{
[OperationContract]
string HelloWorld();
}
After using svcutil
to generate the proxy, I can call HelloWorld()
one of 2 ways:
WebServiceClient proxy = new ServiceReference.WebServiceClient();
textBox1.Text += proxy.HelloWorld();
or:
ChannelFactory<ServiceReference.IWebService2> cfactory =
new ChannelFactory<ServiceReference.IWebService>("BasicHttpBinding_IWebService");
ServiceReference.IWebService proxy = cfactory.CreateChannel();
((IClientChannel)proxy).Open();
textBox1.Text += proxy.HelloWorld();
Now assume this ASMX web service:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{
public WebService() { }
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
}
Calling HelloWorld()
using the SoapClient
generated by svcutil
tool is nearly the same as if it were a WCF web service:
WebServiceSoapClient proxy = new ServiceReference.WebServiceSoapClient();
textBox1.Text += proxy.HelloWorld();
But trying to call HelloWorld()
if you create the channel yourself and you will get an error:
ChannelFactory<ServiceReference.WebServiceSoap> cfactory =
new ChannelFactory<ServiceReference.WebServiceSoap>("WebServiceSoap");
ServiceReference.WebServiceSoap proxy = cfactory.CreateChannel();
((IClientChannel)proxy).Open();
textBox1.Text += proxy.HelloWorld();
The error is "No overload for method HelloWorld takes 0 arguments".
It appears it is because the HelloWorld
method in the autogenerated interface (ServiceReference.WebServiceSoap)
takes an argument of type ServiceReference.HelloWorldRequest
.
So in the end, I was only able to make it work by looking through the svcutil
generated code and change my implementation to this:
ChannelFactory<ServiceReference.WebServiceSoap> cfactory =
new ChannelFactory<ServiceReference.WebServiceSoap>("WebServiceSoap");
ServiceReference.WebServiceSoap proxy = cfactory.CreateChannel();
((IClientChannel)proxy).Open();
ServiceReference.HelloWorldRequest inValue =
new WCFConsumeWebServices.ServiceReference.HelloWorldRequest();
inValue.Body = new WCFConsumeWebServices.ServiceReference.HelloWorldRequestBody();
ServiceReference.HelloWorldResponse retVal = proxy.HelloWorld(inValue);
textBox1.Text += retVal.Body.HelloWorldResult;
Is this how it is suppose to be?
For one type of basic http web service, we get to use virtually the same code to call a method, but for another we need to muck through the generated proxy code and have different implementation depending on how you open the channel ?