Part 1: The Web services empire strikes back - Introductory thoughts
Part 2: The Web services empire strikes back - Inner Workings
Part 3: The Web services empire strikes back - Web Services in Visual Studio 2005
Part 4: The Web services empire strikes back - WS-I BP Conformance
Part 5: The Web services empire strikes back - Custom XML Serialization
Part 6: The Web services empire strikes back - Proxy Type Sharing
Part 7: The Web services empire strikes back - Contract-first with .NET 'IDL'
Part 8: The Web services empire strikes back - Schema Importer Extensions
Part 9: The Web services empire strikes back - Making asynchronous Web service calls easier
Part 10: The Web services empire strikes back - Support for Nullable and SqlTypes
To make the list of advanced data type support complete, we can build on the information just learnt about nullable types. XmlSerializer, and therefore also the ASMX v2 infrastructure, is now capable of serializing and deserializing generic data types that come to the developer’s palm with the .NET Framework 2.0.
The following generics-based declaration of a complex type to model a dictionary entry can be easily used in a Web service operation.
public class MyDictionaryEntry<K, V>
{
private K _key;
private V _value;
public V Value
{
get { return (_value); }
set { _value = value; }
}
public K Key
{
get { return (_key); }
set { _key = value; }
}
}
To use the above MyDictionaryEntry type as a return value for a WebMethod we can write the following method signature:
[WebMethod]
public MyDictionaryEntry<int, string> GetDictEntry()
{
//
}
The ASMX infrastructure properly handles the generics type in our case emits the following schema snippet at runtime when querying the WSDL for the service (which may not be what you are really after ...)
<s:element name="GetDictEntryResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="DictEntry"
nillable="true" type="tns:MyDictionaryEntry2OfInt32String" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="MyDictionaryEntry2OfInt32String">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Value"
type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="Key" type="s:int" />
</s:sequence>
</s:complexType>
The integer and string types we declared for our generics data type get completely mapped into the XSD space. So you can see that the power of closed generics types also comes to the Web services world.
Please note again, that this is not the way you should think of Web services: objects or .NET types. In the middle of the Web services world there is the message. You can model it with the code-first approach as propagated by ASMX and as used throughout this entire article. Or you could approach it from the contract-first corner – but this is a totally different story and leaves enough room for an entire new article.