Press "Enter" to skip to content

C# Evitare problemi con il BOM lavorando con un HTTP Listener

Stiamo implementando un servizio interno (interno vuol dire che lavora in una intranet), per uno dei software della mia azienda, il servizio scambia messaggi con i pc client dove gira l’applicazione. I dati scambiati sono spediti come una classe XML ad un HTTP Listener.

Sembrava tutto semplice eccetto che, quando la classe XML arrivava al listener, il deserializzatore dava i numeri dicendo che la classe non era correttamente formattata.

Dopo una serie di approfondite verifiche sul nostro codice (Io parto sempre dal presupposto che le probabilità che abbia fatto dei danni è maggiore nel codice scritto da me rispetto a quello scritto in una libreria di sistema o un componente di terzi.) Non trovando nulla nel codice dei metodi di serializzazione e deserializzazione, abbiamo predisposto uno sniffer sui dati che arrivavano al listener nella response, abbiamo scoperto che i dati serializzati avevano 3 bytes  che precedevano <?xml l’iniziale di tutti i files XML, in esadecimale si tratta dei valori EB BB BF, non capivamo cosa fosse e dopo aver passato alcuni momenti a pensare che cosa potesse esserci di sbagliato nel nostro codice per  produrre questo problema, abbiamo fatto una ricerca su internet e abbiamo imparato qualcosa di importante (come sempre non si finisce mai di imparare…) Ad ogni modo, abbiamo scoperto che i tre caratteri invisibili sono un BOM (Byte Order Mark – Segno di Ordinamento dei Byte) che è automaticamente aggiunto dai sistemi di serializzazione quando si effettua un encoding  in UTF-8. Notepad, Notepad++ e altri editor di testo o lettori di XML e testo ignorano il BOM pertanto non ci accorgeremo mai di lui ma si trova li. Il problema del mio servizio era dovuto al fatto che deserializzando da una stringa, i tre caratteri non venivano eliminati e il metodo di deserializzazione dava un errore dicendo che c’erano dei caratteri non compatibili all’inizio della classe.

C’è un modo per evitare il problema del BOM? Certo è uno dei parametri forniti al serializzatore da  XmlWriterSettings

XmlWriterSettings xstt = new XmlWriterSettings();
xstt.Encoding = Encoding.UTF8 : new UTF8Encoding(false);
using (XmlWriter writer = XmlWriter.Create(stream, xstt))
{
   ...
}

Usando questa opzione per serializzare la classe, evitiamo che venga generato il BOM e quindi i problemi di deserializzazione.

Spero che questo articolo possa dare una mano a qualcuno con lo stesso problema risparmiandogli tempo e frustrazioni. 😉