Calling a WebReference operation name the same as the Web service name

In the WSDL below, the Web Service is "CalcService" and it contains an operation also called "CalcService". When adding a WebReference to this WSDL, the proxy generated (CalcService class) contains a "CallCalcService" method for the "CalcService" operation - persumeably because a method "CalcService" would be mistaken for a constructor. Calling the "CallCalcService" method tries to invoke a "CallCalcService" operation on the Web Service, which doesn't exist. Calling the other methods on the proxy work fine.

Looking at the code with Reflector, the method passes the "CalcService" method name to SoapHttpClientProtocol.Invoke(), but that this name is then translated in SoapClientType.GetMethod() via a logical table of method names. This table (methods) appears to be set up via Reflection and maps thie "CalcService" name back to "CallCalcService".

< xml version="1.0" encoding="UTF-8" standalone="no" >
<definitions name="CalcService" targetNamespace="http://tempuri.org/CalcService" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://tempuri.org/CalcService" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <!-- Micro Focus NetExpress generated WSDL document-->
    <types>
      <schema elementFormDefault="unqualified" targetNamespace="http://tempuri.org/CalcService" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://tempuri.org/CalcService"/>
    </types>
    <message name="AddInput">
      <part name="num2" type="xs:int"/>
      <part name="num3" type="xs:int"/>
    </message>
    <message name="AddOutput">
      <part name="num1" type="xs:int"/>
    </message>
    <message name="MultiplyInput">
      <part name="num2" type="xs:int"/>
      <part name="num3" type="xs:int"/>
    </message>
    <message name="MultiplyOutput">
      <part name="num1" type="xs:int"/>
    </message>
    <message name="CalcServiceInput"/>
    <message name="CalcServiceOutput">
      <part name="num1" type="xs:int"/>
    </message>
    <portType name="CalcService">
      <operation name="Add">
        <input message="tns:AddInput"/>
        <output message="tns:AddOutput"/>
      </operation>
      <operation name="Multiply">
        <input message="tns:MultiplyInput"/>
        <output message="tns:MultiplyOutput"/>
      </operation>
      <operation name="CalcService">
        <input message="tns:CalcServiceInput"/>
        <output message="tns:CalcServiceOutput"/>
      </operation>
    </portType>
    <binding name="CalcService" type="tns:CalcService">
      <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
      <operation name="Add">
        <soap:operation soapAction=""/>
        <input>
          <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://tempuri.org/CalcService" use="encoded"/>
        </input>
        <output>
          <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://tempuri.org/CalcService" use="encoded"/>
        </output>
      </operation>
      <operation name="Multiply">
        <soap:operation soapAction=""/>
        <input>
          <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://tempuri.org/CalcService" use="encoded"/>
        </input>
        <output>
          <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://tempuri.org/CalcService" use="encoded"/>
        </output>
      </operation>
      <operation name="CalcService">
        <soap:operation soapAction=""/>
        <input>
          <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://tempuri.org/CalcService" use="encoded"/>
        </input>
        <output>
          <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://tempuri.org/CalcService" use="encoded"/>
        </output>
      </operation>
    </binding>
    <service name="CalcService">
      <port binding="tns:CalcService" name="CalcService">
        <soap:address location="http://localhost:9003"/>
      </port>
    </service>
  </definitions>



Answer this question

Calling a WebReference operation name the same as the Web service name

  • mc_hk

    Mark, you are correct: the previous versions of the Web Services Framework had this problem.  I am surprised that you see this behavior with Whidbey Beta2: the problem was fixed on 2004/11/06, and should be in Beta2 drop.

    (VSWhidbey # 401918 To add an online web service, which contains same name in service and web method, can not be established successfully.)

    In the case when method name matches the containing proxy class we use "Call" prefix for the method name.  In your example the method should be called "CallCalcService".  Please check the version comment to see that you are using the most recent version of the Framework.  The fix made in the 50215.44 drop.


  • jeymard

    Hi Todd,
    This is Whidbey, Beta 2.

    I don't think the C# proxy code above is legal- does it compile In C# you can't have a member name the same as a class name (it would get confused with the constructor). I presumed this was why the proxy generator was changing the name.

    Regards,
    Mark.

  • Manuel L.

    Hello Mark,

    What version of the .NET Framework are you using I added a web reference to your WSDL file and also created the proxy class using wsdl.exe. In both cases the I have CalcService for the proxy class name and then I do have a CalcService() method that returns an integer:

    [System.Diagnostics.DebuggerStepThroughAttribute()][System.ComponentModel.DesignerCategoryAttribute("code")][System.Web.Services.WebServiceBindingAttribute(Name="CalcService", Namespace=http://tempuri.org/CalcService)]
    public class CalcService : System.Web.Services.Protocols.SoapHttpClientProtocol {
        /// <remarks/>
        public CalcService() {
        this.Url = http://localhost:9003;
    }

    .
    .
    .
    .
    [System.Web.Services.Protocols.SoapRpcMethodAttribute("", RequestNamespace="http://tempuri.org/CalcService", ResponseNamespace=http://tempuri.org/CalcService)]
    [return: System.Xml.Serialization.SoapElementAttribute("num1")]
    public int CalcService() {
        object[] results = this.Invoke("CalcService", new object[0]);
        return ((int)(results[0]));
    }


    -Todd Foust



  • Calling a WebReference operation name the same as the Web service name