Siamo abituati con i web services in ASP.NET ad utilizzare (spesso incosapevolmente) l'XmlSerializer per serializzare/deserializzare le nostre istanze di classi nel messaggio SOAP. La caratteristica dell'XmlSerializer (fra le altre cose) è di serializzare i tipi primitivi come tipi XML Schema (definiti sotto il namespace http://www.w3.org/2001/XMLSchema). In Indigo, se definiamo il seguente contratto:
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
}
lo schema generato produrrà qualche cosa di veramente nuovo:
<xs:element name="Add">
<xs:complexType>
<xs:sequence>
<xs:element name="n1" xmlns:q1="http://schemas.microsoft.com/2003/10/Serialization/" type="q1:double" />
<xs:element name="n2" xmlns:q2="http://schemas.microsoft.com/2003/10/Serialization/" type="q2:double" />
</xs:sequence>
</xs:complexType>
</xs:element>
perchè è stato definito il tipo double (primitivo) sotto un'altro namespace ? In sostanza, by default, Indigo non usa l'XmlSerializer bensì l'XmlFormatter. L'XmlFormatter è un pò il successore del SoapFormatter (quindi può serializzare anche membri privati e protetti). Ha delle caratteristiche che lo rendono decisamente interessante, quali:
- supporta le Hashtable (finalmente!)
- supporta una serie di eventi OnDeserialized, OnSerialized, OnSerializing e OnDeserializing
- permette di gestire sia l'accoppiamento debole (come fa l'XMLSerializer oggi) che forte (come fa il .NET Remoting oggi)
- ....
Se è necessario mantenere una compatibilità massima con i tipi XSD (Xml Schema) allora è possibile forzare il ServiceContract ad utilizzare l'XmlSerializer aggiungendo un parametro nell'attributo:
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples",
FormatMode = ContractFormatMode.XmlSerializer)]
public interface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
}
che produrrà
<xs:schema xmlns:tns="http://Microsoft.ServiceModel.Samples" elementFormDefault="qualified" targetNamespace="http://Microsoft.ServiceModel.Samples" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Add">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="n1" type="xs:double" />
<xs:element minOccurs="1" maxOccurs="1" name="n2" type="xs:double" />
</xs:sequence>
</xs:complexType>
</xs:element>