2012-04-02 2 views
6

Per semplificare questo aspetto, il massimo che conosco sulla codifica del testo ho imparato dall'articolo Joel Spolsky.Come gestisco correttamente UTF-8 nelle risposte web nel mio codice C#?

Attualmente sto scrivendo un sistema web C# per eseguire una query sulla nostra appliance di ricerca Google, leggere i risultati e presentarli all'utente nella nostra interfaccia utente personalizzata. Tuttavia, ci sono problemi di codifica quando sto visualizzando i riepiloghi di testo agli utenti.

Quando interrogo la GSA direttamente in cromo/IE/qualunque cosa, ottengo la seguente risposta

post partita Note No. 8 semi DePaul vs. No. 9 seme USF gioco 6 - Secondo
rotonda

Nel mio codice C#, sto leggendo che la risposta con il seguente codice:

 var request = WebRequest.Create(LastQueryUrl); 
     var response = (HttpWebResponse)request.GetResponse(); 

     if (response.StatusCode != HttpStatusCode.OK) 
      return null; 

     using (var reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8)) 
      content = reader.ReadToEnd(); 

Quando il debug la variabile content, vedo che stringa trasformato in:

USF gioco 6 seconda

Sono sicuro al 99% che i dati provenienti dal GSA siano in formato UTF-8 a causa di altri punti sul loro xml che lo dichiarano così come da varie informazioni nella documentazione. Anche se, se leggo lo stream utilizzando System.Text.Encoding.Unicode, non è leggibile alcuno del testo.

Cosa sto facendo male e come posso visualizzare correttamente il testo?


Edit: usando System.Text.Encoding.GetEncoding("ISO-8859-1") mi dà

USF gioco 6 Seconda

No punto di domanda, anche se il cruscotto non si presenta.

+0

Il tuo codice sembra corretto. Per aiutarci a identificare il problema, potresti sostituire temporaneamente la codifica con 'System.Text.Encoding.GetEncoding (" ISO-8859-1 ")' e incollare qui la stringa renderizzata? – Douglas

+1

La ragione per cui sto suggerendo ISO-8859-1 (Latin-1) è che, anche se non corrisponde alla codifica originale del tuo testo, fornisce comunque un mapping uno-a-uno tra tutti i valori di 256 byte e un carattere, permettendoci così di dedurre quali valori di byte stai effettivamente ricevendo. – Douglas

+0

Aggiornato con quello. Aiuta, non ancora al 100%. – KallDrexx

risposta

2

Provare a eseguire questo codice (anziché il blocco using) e incollare di nuovo il risultato? Sto assumendo sei in .NET 4.

using (var responseStream = response.GetResponseStream()) 
using (var memoryStream = new MemoryStream()) 
{ 
    responseStream.CopyTo(memoryStream); 
    byte[] bytes = memoryStream.ToArray(); 
    content = BitConverter.ToString(bytes); 
} 

Edit: Ho notato che non siete stati incollando l'intera stringa restituita nei tuoi post. È perché il resto della stringa contiene dati riservati? In tal caso, non incollare il risultato suggerito sopra.

Edit: Per ottenere il risultato di rendere correttamente, è possibile utilizzare Encoding.GetEncoding(1252); tuttavia, suggerirei di non farlo, per ragioni che spiegherò presto.

Spiegazione: Da quello che ho capito, il problema sembra essere che il mittente è sempre loro codifiche sbagliato.Tu dici che la loro documentazione sostiene UTF-8, che è chiaramente contraddetto dalla loro dichiarazione XML ISO-8859-1. In realtà, la codifica utilizzata non è l'una né l'altra.

Nella stringa esadecimale caricata, il carattere colpevole ha un valore di byte di 0x96 e si trova nel mezzo della sequenza 20-96-20. Sia in UTF-8 che in ISO-8859-1 (così come ASCII prima di loro), 0x20 è un carattere di spazio. Tuttavia, in UTF-8, 0x96 è un byte di continuazione ed è not valid a meno che non sia preceduto da un byte iniziale (che non è 0x20). In ISO-8859-1, 0x96 è un carattere di controllo C1 e, pertanto, non un carattere stampabile (non può essere visualizzato agli utenti).

Quindi, possiamo dedurre che la codifica carattere originale è né UTF-8 né ISO-8859-1, ma Windows-1252, talvolta considerato un “superset” ISO-8859-1 dal momento che sostituisce il 0x80 - gamma di 0x9F controlla i caratteri per caratteri visualizzabili. In effetti, in Windows-1252, 0x96 è il carattere en-dash che si aspettava.

In considerazione di quanto sopra, potrebbe essere sicuro risolvere il problema assumendo la codifica Windows-1252; tuttavia, se fossi in te, vorrei contattare il fornitore e informarli di questo difetto.

using (var stream = response.GetResponseStream()) 
using (var reader = new StreamReader(stream, System.Text.Encoding.GetEncoding(1252))) 
    content = reader.ReadToEnd(); 
+0

È troppo grande per incollare, quindi ho caricato il risultato in http://dl.dropbox.com/u/6753359/gsaBytes.txt – KallDrexx

+0

No, ho incollato solo le parti pertinenti sopra per brevità. È un XML composto da 20 risultati di ricerca che verranno visualizzati dagli utenti pubblici. – KallDrexx

+0

Lo sto analizzando; dammi qualche minuto e tornerò da te. – Douglas

1

La specifica HTML5 richiede che i documenti pubblicizzato come ISO-8859-1 effettivamente essere analizzati con la codifica Windows-1252.

+0

Beh, questo rende questo un po 'più sensato – KallDrexx