2009-06-09 6 views
15

Sto cercando di creare un pezzo di XML. Ho creato i dataclass con xsd.exe. La classe radice è MESSAGE.XmlTextWriter problema di serializzazione

Così, dopo aver creato un MESSAGE e riempiendo tutte le sue proprietà, ho serializzare in questo modo:

serializer = new XmlSerializer(typeof(Xsd.MESSAGE)); 
StringWriter sw = new StringWriter(); 
serializer.Serialize(sw, response); 
string xml = sw.ToString(); 

Fino ad ora tutto va bene, l'XML stringa contiene valido (UTF-16 codificato) xml. Ora mi piace creare l'XML con codifica UTF-8, invece, in modo da fare in questo modo:

Edit: dimenticato di includere la dichiarazione del torrente

serializer = new XmlSerializer(typeof(Xsd.MESSAGE)); 
using (MemoryStream stream = new MemoryStream()) 
{ 
    XmlTextWriter xtw = new XmlTextWriter(stream, Encoding.UTF8); 
    serializer.Serialize(xtw, response); 
    string xml = Encoding.UTF8.GetString(stream.ToArray()); 
} 

E qui viene il problema : Utilizzando questo approccio, la stringa xml è preceduta da un carattere non valido (il famigerato quadrato).
Quando ho ispezionare il char in questo modo:

char c = xml[0]; 

posso vedere che c ha un valore di 65279.
Qualcuno ha idea di dove questo viene da?
posso facilmente risolvere questo tagliando il primo carattere:

xml = xml.SubString(1); 

ma preferirei sapere che cosa sta succedendo che tagliare alla cieca del primo carattere.

Chiunque può far luce su questo? Grazie!

+0

See: http://stackoverflow.com/questions/955611/xmlwriter-to-write-to-a -string-instead-to-a-file/955698 # 955698 –

risposta

15

Ecco il tuo codice modificato di non anteporre il byte-order-mark (BOM):

var serializer = new XmlSerializer(typeof(Xsd.MESSAGE)); 
Encoding utf8EncodingWithNoByteOrderMark = new UTF8Encoding(false); 
XmlTextWriter xtw = new XmlTextWriter(stream, utf8EncodingWithNoByteOrderMark); 
serializer.Serialize(xtw, response); 
string xml = Encoding.UTF8.GetString(stream.ToArray()); 
+0

Ho usato questa soluzione, quindi ho accettato questa risposta. Grazie! – fretje

6

65279 è il segno di ordine dei byte Unicode - sei sicuro che stai ricevendo 65249? Supponendo che in realtà è la distinta base, si potrebbe sbarazzarsi di esso con la creazione di un'istanza di UTF8Encoding, che non fa uso di una distinta base. (Vedere gli overload del costruttore per i dettagli.)

Tuttavia, c'è un modo più semplice di ottenere UTF-8 out. È possibile utilizzare StringWriter, ma una classe derivata che sovrascrive la proprietà Encoding. Vedi this answer per un esempio.

+0

Ho eseguito il codice e ottenuto anche 65279. Probabilmente un errore di battitura nella domanda. –

+0

Un errore di battitura in effetti ... aggiornato ;-) – fretje

+0

BOM: Vedi http://en.wikipedia.org/wiki/Byte-order_mark –