Question

I've started using some web services that have a staggering amount of redundancy when added as web services in Visual Studio 2012. Here are two WSDLs that demonstrate this:

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

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

These are services to create a new session and to close it, respectively. Each service has its own MessageHeader class, which in turn has a member that's from a MessageData class that's redefined in every generated proxy. There are others like this but I won't name them all.

This makes it difficult when I want to create a helper function that sets up my request and fills in all the common stuff in the envelope such as timestamps, authentication, etc. because Service1.MessageHeader is not the same type as Service2.MessageHeader. I've experimented with duck typing, but as far as I've seen the nested nature of this would prevent that approach.

Looking at the WSDL, these classes are all defined as being from the same namespaces. In other words, in both WSDLs, MessageHeader is defined as:

<xsd:import namespace="http://www.ebxml.org/namespaces/messageHeader" schemaLocation="msg-header-2_0.xsd"/>
...
<part name="header" element="eb:MessageHeader"/>

Is there some way to make VS understand that these are the same thing in both classes and somehow get it to separate them out as common to both? Or is it "a web service is an island"? I'd really rather not have to create separate code for every single type of web service I'll need, as there are far more than just these two. But every one of them uses these same classes.

I've thought about going in and hacking up the proxy classes by hand. But beyond my fear that this would make VS slip some gear because I'd messed up what it was doing behind the scenes that it never expected me to tinker with, I'd lose the whole auto-generation should something change in the WSDL that needed resyncing.

I've tried this both in C# and in Oxygene and run into the same issues. I imagine it'd be the same in other languages under VS. It seems related to how it understands WSDL.

Before anyone asks, I can't change anything about the actual web services. That is another company altogether, and not one that will be interested in redesigning their widely used system based on my whims.

Was it helpful?

Solution

I've found a potential solution to this, and it works in every way I can tell. But I'm open to criticisms or "a better way" (including a better way to do it from the GUI).

I've found that using the following command generates the proper "single unit" type of interface I want with all the types shared:

 wsdl.exe /sharetypes /language:CS "http://webservices.sabre.com/wsdl/sabreXML1.0.00/usg/SessionCreateRQ.wsdl" "http://webservices.sabre.com/wsdl/sabreXML1.0.00/usg/SessionCloseRQ.wsdl" /o:"SabreWebServices.cs" /n:SabreWebServices

That creates a C# one. For Oxygene, I use:

 wsdl.exe /sharetypes /language:OXYGENE "http://webservices.sabre.com/wsdl/sabreXML1.0.00/usg/SessionCreateRQ.wsdl" "http://webservices.sabre.com/wsdl/sabreXML1.0.00/usg/SessionCloseRQ.wsdl" /o:"SabreWebServices.pas" /n:SabreWebServices

FWIW, I used the wsdl from the "c:\Program Files\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools directory on my machine.

I added the resulting wrapper file to my application and it worked perfectly, if a bit differently than the wrappers created through Add Service Reference. I actually prefer the syntax this created a bit more. It also had the benefit of creating only the one file rather than numerous ones and not mucking with app.config. If you want to change the endpoint, you can just set the Url property of whichever service you instantiate.

I arrived at this solution at this post this via this post.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top