views:

4409

answers:

6

Hi there,

I am chipping away at building a client for a Java B2B web-service at the moment and I think I have identified the cause of a problem we have been having for quite some time. Unfortunately I'm unable to post the WSDL.

Apparently my auto-generated proxy code (via wsdl.exe: have to use WSE 3.0 due to WCF not supporting password digest) is not able to handle the web-service's WSDL having multiple web-methods with the same complex return type.

Take for example - a web-service that defines the following methods:

Public ComplexTypeX Blah();
Public ComplexTypeX Blue();
Public ComplexTypeX Foo();
Public ComplexTypeY Bar();

In my Reference.cs file, if I comment out all code that calls any two of Blah(), Blue() or Foo(), then the remaining uncommented method can be called no problem. However, if I have more than one of these three methods not commented out (say, Blah() and Foo()), then I get the following error message upon instantiation of the web-service client code:

"Method Blah can not be reflected." "The XML element 'ComplexTypeX' from namespace 'http://some.url' references a method and a type. Change the method's message name using WebMethodAttribute or change the type's root element using the XmlRootAttribute."

Now, there is definitely no ComplexTypeX method defined as part of the web-service, so I can only assume that .NET (or at least wsdl.exe) does not allow you to use a web-service that returns complex (user-defined) types of the same type accross multiple methods ... right?

Cheers,

Bernard.

A: 

so I can only assume that .NET (or at least wsdl.exe) does not allow you to use a web-service that returns complex (user-defined) types of the same type accross multiple methods ... right?

This is incorrect. Imagine how much of a pain that would be if it were true - you could only ever have one method that returns a String, one that returns a Double, one that returns SomeObject, etc... it would be a nightmare.

I'm not very familiar with web services in .NET, but from the errors you are getting it sounds like you are having issues with the XML namespaces - perhaps there is a name collision. I'd attempt to follow the suggestion in the error message, to modify the WebMethodAttribute.

Also in addition, if you are unable to post a piece of code/document related to the trouble you are having because of some company privacy/sensitivity issues, you should post a sanitized version that still proves your test case. Almost anything "sensitive" should be able to be boiled down to a far more simpler snippet of code that still gets your point across without betraying any sensitivities.

matt b
A: 

Very odd. Normally the WSDL would provide a common type, and when compiled through wsdl.exe or svcutil.exe, you'd get a shared, common type to use across any number of methods in the same interface.

There have been problems when referencing multiple independent WSDL's in the same app, that share an ostensibly identical type, which results in two distinct CLR types being generated. There are ways around this problem - it's fairly well known. Then there is the somewhat-related problem of mapping an existing business object to a type generated from a WSDL. Another previously explored landscape.

But you are talking about something different.

Cheeso
Do you have a link to solutions to the problem about referencing multiple independant WSDLs with the same types? I'm having this problem at the moment.
Helephant
Cheeso
+1  A: 

I just searched for "references a method and a type" and found a Connect bug report "System.InvalidOperationException: The XML element * from namespace * references a references a method and a type". In this case, there is an operation and an element with the exact same name (both local name and namespace).


It's worth noting part of the response from Microsoft:

We're no longer making enhancements to ASMX; we continue to support its existing functionality, but where possible, we recommend using WCF instead.

John Saunders
A: 

Use WSDL.exe has a switch /sharetypes. This should take care of the issue.

Moreover I would not agree that its a Microsoft thing as same classes are exposed as different complex types sitting in multiple wsdl. Thats not a good abstracted design.

Ready Reference Microsoft Documentation for sharetypes Turns on type sharing feature. This feature creates one code file with a single type definition for identical types shared between different services (namespace, name and wire signature must be identical). Reference the services with http:// URLs as command-line parameters or create a discomap document for local files.

Pranav Shah
This would not have resolved the problem in http://stackoverflow.com/questions/580042/c-web-service-client-multiple-web-service-methods-with-same-complex-return-ty/1164877#1164877.
John Saunders
A: 

Below pasted my wsdl file. I am unable to return user defined dat types from .Net client. Can anyone please suggest how to return user defined data types from .Net client. I created a java web service and trying to invoke it on .Net client.

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="EmployeeDetails" targetNamespace="http://service.testing/"
       xmlns:ns1="http://cxf.apache.org/bindings/xformat" 
       xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
       xmlns:tns="http://service.testing/"
       xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
    <wsdl:types>
        <xs:schema attributeFormDefault="unqualified" elementFormDefault="unqualified" 
          targetNamespace="http://jaxb.dev.java.net/array" 
          xmlns="http://jaxb.dev.java.net/array" 
          xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;
            <xs:complexType final="#all" name="stringArray">
                <xs:sequence>
                    <xs:element maxOccurs="unbounded" minOccurs="0" name="item" nillable="true" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>
        </xs:schema>
        <xs:schema attributeFormDefault="unqualified" elementFormDefault="unqualified"
           targetNamespace="http://service.testing/" xmlns="http://service.testing/" 
           xmlns:ns0="http://jaxb.dev.java.net/array" 
           xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;
            <xs:import namespace="http://jaxb.dev.java.net/array"/&gt;
            <xs:complexType name="employee">
                <xs:sequence>
                    <xs:element minOccurs="0" name="desgnation" type="xs:string"/>
                    <xs:element minOccurs="0" name="employeeCode" type="xs:int"/>
                    <xs:element minOccurs="0" name="name" type="xs:string"/>
                    <xs:element minOccurs="0" name="phoneNo" type="xs:int"/>
                </xs:sequence>
            </xs:complexType>
            <xs:element name="details" nillable="true" type="ns0:stringArray"/>
            <xs:element name="getEmployeeResponse" nillable="true" type="employee"/>
            <xs:element name="Employee" nillable="true" type="employee"/>
            <xs:element name="EmployeeDetails" nillable="true" type="xs:string"/>
        </xs:schema>
    </wsdl:types>
    <wsdl:message name="getEmployeeResponse">
        <wsdl:part element="tns:getEmployeeResponse" name="getEmployeeResponse"/>
    </wsdl:message>
    <wsdl:message name="getEmployeeDetails">
        <wsdl:part element="tns:Employee" name="Employee"/>
    </wsdl:message>
    <wsdl:message name="getEmployee">
        <wsdl:part element="tns:details" name="details"/>
    </wsdl:message>
    <wsdl:message name="getEmployeeDetailsResponse">
        <wsdl:part element="tns:EmployeeDetails" name="EmployeeDetails"/>
    </wsdl:message>
    <wsdl:portType name="EmployeeService">
        <wsdl:operation name="getEmployee">
            <wsdl:input message="tns:getEmployee" name="getEmployee"/>
            <wsdl:output message="tns:getEmployeeResponse" name="getEmployeeResponse"/>
        </wsdl:operation>
        <wsdl:operation name="getEmployeeDetails">
            <wsdl:input message="tns:getEmployeeDetails" name="getEmployeeDetails"/>
            <wsdl:output message="tns:getEmployeeDetailsResponse" name="getEmployeeDetailsResponse"/>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="EmployeeDetailsSoapBinding" type="tns:EmployeeService">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/&gt;
        <wsdl:operation name="getEmployee">
            <soap:operation soapAction="" style="document"/>
            <wsdl:input name="getEmployee">
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output name="getEmployeeResponse">
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="getEmployeeDetails">
            <soap:operation soapAction="" style="document"/>
            <wsdl:input name="getEmployeeDetails">
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output name="getEmployeeDetailsResponse">
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="EmployeeDetails">
        <wsdl:port binding="tns:EmployeeDetailsSoapBinding" name="EmployeeServiceImplPort">
            <soap:address location="http://localhost:8080/Test6/services/details"/&gt;
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>
Welcome to stackoverflow. To ask a question, please see "Ask Question" at the top of the page. You've pasted this as a reply to an existing question, which won't really help you get answers.
Marc Gravell
Also, please do not copy and paste XML from Internet Explorer. You pasted in the "-" signs that IE uses to expand and collapse the XML, so it was no longer XML. Finally, when you paste XML or code, select the code in the editor and press Control-K.
John Saunders
+1  A: 

I ran into a similar problem, and here is what I found:

I had defined a complex type to return as a response:

public class FooResponse {...}

[WebMethod]
public FooResponse Foo() {...}

Note that here the exact name pairing of Foo/Foo+Response is important. When I changed the method name as follows, the problem went away:

public class FooResponse {...}

[WebMethod]
public FooResponse Fooxxx() {...}

What I believe is happening is .NET is attempting to automatically wrap the response coming from the Foo method with an element named FooResponse. The use of that same name as the object you want to return creates ambiguity. Try changing the name of your response object, or the name of your method to avoid this collision.

Ryan Morlok