Chi ha usato la classe XmlSerializer si sarà accorto di quanto questa sia flessibile e libertina. In pratica possiamo scrivere di tutto e lei continuerà a serializzare/deserializzare senza timori. Se trova l'elemento bene, altrimenti la inizializza in base al tipo base.
Se questo approccio funziona bene per serializzazioni di classi su files, può provocare non pochi grattacapo nel caso di web services. Prendiamo un esempio molto semplice (il più semplice) di WebMethod che somma due numeri:
<%@ WebService Language="c#" Class="Math" %>
using System.Web.Services;
[WebService(Namespace="urn:ugidotnet:org:services:tests")]
public class Math
{
[WebMethod]
public int Add(int a, int b)
{
return a + b;
}
}
Prendiamo un qualsiasi client di web services (es .NET WebService Studio) e effettuiamo una chiamata al web service passando 12 e 23 per a e b rispettivamente. La risposta sarà ovviamente 35 !
Se guardiamo il messaggio SOAP spedito per la richiesta di addizione troviamo il seguente stream:
<?xml version="1.0" encoding="utf-16"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<Add xmlns="urn:ugidotnet:org:services:tests">
<a>12</a>
<b>23</b>
</Add>
</soap:Body>
</soap:Envelope>
Il tutto sembra funzionare. Proviamo ora a cambiare la riga <a>12</a> con <A>12</A>. Essendo l'XML case-sensitive ci attendiamo un bel errore. Invece no !! Il risultato della somma sarà 23 !
Perchè questo ? Semplice, l'XmlSerializer quando deserializza non trova l'elemento a e quindi lo inizializza a 0 (valore di default di un System.Int32). Quindi lo passa al metodo il quale non avvertirà alcun tipo di errore e calcolerà la somma.
C'è una soluzione a tutto questo ? Certamente, ma sarà oggetto di un prossimo blog....lo debbo ancora sviluppare :-))