title: Accessing asmx WebService Using WCF
body: <p>I am trying to access an old ASMX webservice using WCF by calling the <code>ChannelFactory.CreateChannel()</code> method.</p>
  
  <p>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 <code>ChannelFactory.CreateChannel()</code> method. Afterwards, I can call the web service methods the same way for both scenarios.</p>
  
  <p>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.</p>
  
  <p>For example, assume this basic WCF web service interface:</p>
  
  <pre><code>[ServiceContract]
  public interface IWebService
  {
      [OperationContract]
      string HelloWorld();
  }
  </code></pre>
  
  <p>After using <code>svcutil</code> to generate the proxy, I can call <code>HelloWorld()</code> one of 2 ways:</p>
  
  <pre><code>WebServiceClient proxy = new ServiceReference.WebServiceClient();
  textBox1.Text += proxy.HelloWorld();
  </code></pre>
  
  <p>or:</p>
  
  <pre><code>ChannelFactory&lt;ServiceReference.IWebService2&gt; cfactory = 
      new ChannelFactory&lt;ServiceReference.IWebService&gt;("BasicHttpBinding_IWebService");
  ServiceReference.IWebService proxy = cfactory.CreateChannel();
  ((IClientChannel)proxy).Open();
  textBox1.Text += proxy.HelloWorld();
  </code></pre>
  
  <p>Now assume this ASMX web service:</p>
  
  <pre><code>[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";
      }
  }
  </code></pre>
  
  <p>Calling <code>HelloWorld()</code> using the <code>SoapClient</code> generated by <code>svcutil</code> tool is nearly the same as if it were a WCF web service:</p>
  
  <pre><code>WebServiceSoapClient proxy = new ServiceReference.WebServiceSoapClient();
  textBox1.Text += proxy.HelloWorld();
  </code></pre>
  
  <p>But trying to call <code>HelloWorld()</code> if you create the channel yourself and you will get an error:</p>
  
  <pre><code>ChannelFactory&lt;ServiceReference.WebServiceSoap&gt; cfactory =
       new ChannelFactory&lt;ServiceReference.WebServiceSoap&gt;("WebServiceSoap");
  ServiceReference.WebServiceSoap proxy = cfactory.CreateChannel();
  ((IClientChannel)proxy).Open();
  textBox1.Text += proxy.HelloWorld();
  </code></pre>
  
  <p>The error is "No overload for method HelloWorld takes 0 arguments".</p>
  
  <p>It appears it is because the <code>HelloWorld</code> method in the autogenerated interface <code>(ServiceReference.WebServiceSoap)</code> takes an argument of type <code>ServiceReference.HelloWorldRequest</code>.</p>
  
  <p>So in the end, I was only able to make it work by looking through the <code>svcutil</code> generated code and change my implementation to this:</p>
  
  <pre><code>ChannelFactory&lt;ServiceReference.WebServiceSoap&gt; cfactory = 
      new ChannelFactory&lt;ServiceReference.WebServiceSoap&gt;("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;
  </code></pre>
  
  <p>Is this how it is suppose to be?</p>
  
  <p>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 ?</p>