views:

521

answers:

3

Hi,

I am currently developing a webapp based on c# that calls some webservices. I have imported three different WSDLs from the provider into my WebApplication3 project (references -> add web reference). In the class viewer they appear as:

WebApplication3.com.provider.webservices1
WebApplication3.com.provider.webservices2
WebApplication3.Properties

Apparently the first and second WSDL have repeated functions (is that the correct name?)
If I add to my Default.aspx.cs the following using:

using WebApplication3.com.sabre.webservices1;
using WebApplication3.com.sabre.webservices2;
using WebApplication3.Properties;


and then try using:

MessageHeader msgHeader = new MessageHeader();
in my WebApplication3 namespace, I get the error

"Ambiguous reference between WebApplication3.com.provider.webservices1 and WebApplication3.com.provider.webservices2"

I guess this is because it is declared in both WSDL? How can I fix this so I can use it?

Thanks, and sorry if the question is stupid!

A: 

It would seem as though you have imported the same WSDL twice -- or at least some of the types used by both are the same. You may be able to disambiguate between the two same-named types not importing both web reference namespaces or by using a namespace alias.

Could you post the actual code snippet and also indicate the URLs that you imported using "Add Web Reference"? Also, what version of Visual Studio are you using and what version of the .Net Framework are you targeting?

EDIT -- Follow-up based on the information Peter provided in the comment

I Examined both the URLs you posted, and just wanted to provide a little background. In deed the reason you first saw the error is that both WSDL imports specify the use of the same type, namely MessageHeader. Examining the top of each WSDL file:

http://webservices.sabre.com/wsdl/sabreXML1.0.00/usg/SessionCreateRQ.wsdl

<definitions targetNamespace="https://webservices.sabre.com/websvc"&gt;
  <types>
    <xsd:schema>
    <xsd:import namespace="http://www.opentravel.org/OTA/2002/11" schemaLocation="SessionCreateRQRS.xsd"/>
    <xsd:import namespace="http://www.ebxml.org/namespaces/messageHeader" schemaLocation="msg-header-2_0.xsd"/>
    ...

http://webservices.sabre.com/wsdl/sabreXML1.0.00/tpf/OTA_AirAvailLLS1.1.1RQ.wsdl

<definitions targetNamespace="https://webservices.sabre.com/websvc"&gt;
  <types>
  <xsd:schema>
    <xsd:import namespace="http://webservices.sabre.com/sabreXML/2003/07" schemaLocation="OTA_AirAvailLLS1.1.1RQRS.xsd"/>
    <xsd:import namespace="http://www.ebxml.org/namespaces/messageHeader" schemaLocation="msg-header-2_0.xsd"/>
    ...

The last line in each WSDL file shows the reason for your type name collision -- the same XSD file is imported by each WSDL file, obviously because both use the same type. When you create a web reference to each WSDL file, Visual Studio examines the WSDL and generates a class that matches the imported *msg-header-2_0.xsd* schema.

Unfortunately, Visual Studio can't tell that the schema in each separate WSDSL reference is really the same type, and so it dutifully imports each and generates a separate class for each. Although each of the classes generated share the same name, each is defined within it's own unique namespace that correlates to each of the WSDL files.

So, this is why the solution you accepted for your question works -- either specifying the full name of one the types works or using an alias to one of the types within one of the specific namespace.

Another solution would be to fix the two web references to share a single MessageHeader type. This could be done manually, however, you'd have to redo the manual edit each time you refreshed the web service reference, so I wouldn't recommend it. Also, it's probably a better idea to use the proper MessageHeader type defined for with each service, despite the fact that they're the same. So, I would create two using aliases if you assuming you were going to call both services from the same source file:

using MessageHeader1 = WebApplication3.com.sabre.webservices1.MessageHeader;
using MessageHeader2 = WebApplication3.com.sabre.webservices2.MessageHeader;

I would use MessageHeader1 with whatever service you referenced under the namespace WebApplication3.com.sabre.webservices1 and likewise, MessageHeader2 with the other.

Good luck!

Peter Meyer
http://webservices.sabre.com/wsdl/sabreXML1.0.00/usg/SessionCreateRQ.wsdlhttp://webservices.sabre.com/wsdl/sabreXML1.0.00/tpf/OTA_AirAvailLLS1.1.1RQ.wsdlI am targetting .NET 3.5 using the visual Web Developer Express 2008 (planning to buy studio if this works!)
+3  A: 

try referencing MessageHeader by using its full namespace. eg.

WebApplication3.com.provider.webservices1.MessageHeader msgHeader = new 
WebApplication3.com.provider.webservices1.MessageHeader()

for brevity you can try

using MessageHeader = WebApplication3.com.provider.webservices1.MessageHeader

which would let you use

MessageHeader msgHeader = new MessageHeader()

where MessageHeader is from the webservices1 namespace

Zahir
A: 

Fully qualify the class name with the namespace.

WebApplication3.com.sabre.webservices1.MessageHeader msgHeader = new WebApplication3.com.sabre.webservices1.MessageHeader();
George
That worked, thanks!