.NET Web Service Clients Give You No Choice
(How’s that for a provocative post title? I can’t wait for the flames!)
I’m doing a lot of web services interop work with Java and .NET. I’ve got a Windows Forms application calling a Java web service over SOAP. The Java application behind that web service “does stuff,” and then turns around calls a .NET web service via HTTP GET. It’s a lot of fun stitching this stuff together. More or less.
I discovered several weeks ago that Microsoft’s wsdl.exe
tool immediately barfs when it encounters a <choice>
element in the schema. It does this because, if you think about it a little bit, a <choice>
is really hard! The <choice>
element is the XML equivalent of C’s union
keyword. It allows multiple structures to be defined as valid in a certain space, but which structure will actually be there is unknown until run time. Generating C# code for something like that is rought.
Here’s a way they could have done it, though: Take the elements actually in the <choice>
and give them a common interface. Then you can put the interface in place of the classes generated for the <choice>
’s child schemas. You can then just recurse through all of the structures allowed by the <choice>
element, and generate the code as usual. At run-time, you can figure out which structure you have using a simple is
statement.
Why use an interface? Imagine that, somewhere in your schema, you have a <choice>
that looks like this:
<choice>
<element type="e1" />
<element type="e2" />
</choice>
The classes E1
and E2
get generated from the types e1
and e2
, respectively, and that their base class is given the name B1
. Then, later on, you have a <choice>
that looks like this:
<choice>
<element type="e2" />
<element type="e3" />
</choice>
So what do you do? You either need to generate a different class for e2
schema type here, or the generated class E2
has to have multiple base classes. Since you can’t do multiple inheritence in .NET, implementing multiple interfaces is the next best thing. So each <choice>
gets an interface generated for it.
It all seems to work in my head, but admittedly I haven’t tried it. Watchu think?