So, what was wrong with the approach in the last post?
Firstly, we started by creating the method first. Although this seems natural to most developers, by doing this we are explicitly defining the datatypes in the method before thinking about how they will be translated on the wire.
public boolean MyWebMethod(float price)
In this example, who knows what float and/or boolean is going to map to? We hope that this will be XSD compliant types, but there's never any guarantee. For interoperability between two different platforms, we really don't have any visibility (or control) as to what those types will be mapped to:
Java boolean -> ? -> .NET boolean
This get's even more blurred had we used collection classes or other types without any specific mapping.
Java ArrayList -> ???
Here, we could see any number of outcomes - the most common of which would be to map the array to xsd:anyType, which is going to be very difficult to serialize on the .NET client.
To correct this, the best approach would have been to start with the XSD first. Here's an XSD that contains a very simple boolean and float message type. I've named them according for this example, but in the real world I may have used something that's representative of the business (e.g. price, and priceResult).
<xs:schema id="PrimitiveMessages" targetNamespace="http://schemas.samples.microsoft.com/PrimitiveMessages.xsd" elementFormDefault="qualified" xmlns="http://schemas.samples.microsoft.com/PrimitiveMessages.xsd" xmlns:mstns="http://schemas.samples.microsoft.com/PrimitiveMessages.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:complexType name="BooleanMessageType"> <xs:sequence> <xs:element name="content" type="xs:boolean" /> </xs:sequence> </xs:complexType> <xs:complexType name="FloatMessageType"> <xs:sequence> <xs:element name="content" type="xs:float" /> </xs:sequence> </xs:complexType> <xs:element name="BooleanMessage" type="BooleanMessageType"></xs:element> <xs:element name="FloatMessage" type="FloatMessageType"></xs:element></xs:schema>
Because I've started by using the lowest common denominator (the XSD types), I know that this has the best chance of working between different platforms. Using tools on both platforms, I can now create classes from this XSD file.
In .NET, I would use XSD.EXE from the command line with the /c switch. In Java, it often depends which toolkit you are using. BEA WebLogic supports the option of dropping the .XSD file into the Schemas folder to create XMLBeans. Other toolkits use a Schema2Java command line tool to generate the classes.
Once the classes are generated, my method is updated to reflect these new types:
public BooleanMessageType MyWebMethod(FloatMessageType price)
This leads into the second advantage of this approach. Once I get into the habit of using types - even for simple messages, if I wish to add more data to the message in the future I can often do this without changing the method signature. If I wanted to be even more adventurous I could also consider mapping all my organization's data elements in XSD and then creating a repository where other developers could use the same types for their services.
As I've said, this definitely consitutes as a 'tip' - or recommendation. It may or may not work for you depending on your situation or requirements, but with the little up-front effort to get this working, I've seen this pay dividends for many Web services implementations.