Come GetBytes () in C # con la codifica UTF8 con BOM?

Sto riscontrando un problema con la codifica UTF8 nella mia applicazione asp.net mvc 2 in C #. Sto cercando di consentire all’utente di scaricare un semplice file di testo da una stringa. Sto cercando di ottenere array bytes con la seguente riga:

var x = Encoding.UTF8.GetBytes(csvString);

ma quando lo restituisco per il download utilizzando:

return File(x, ..., ...);

Ricevo un file senza BOM, quindi non visualizzo correttamente i caratteri croati. Questo perché il mio array di byte non include BOM dopo la codifica. Io triend inserendo questi byte manualmente e poi si presenta correttamente, ma non è il modo migliore per farlo.

Ho anche provato a creare un’istanza di class UTF8Encoding e passare un valore booleano (true) al suo costruttore per includere BOM, ma non funziona neanche.

Qualcuno ha una soluzione? Grazie!

Prova così:

 public ActionResult Download() { var data = Encoding.UTF8.GetBytes("some data"); var result = Encoding.UTF8.GetPreamble().Concat(data).ToArray(); return File(result, "application/csv", "foo.csv"); } 

Il motivo è che il costruttore UTF8Encoding che accetta un parametro booleano non fa ciò che ci si aspetterebbe:

 byte[] bytes = new UTF8Encoding(true).GetBytes("a"); 

La matrice risultante conterrebbe un singolo byte con il valore di 97. Non esiste una distinta base perché UTF8 non richiede una distinta componenti.

Ho creato un’estensione semplice per convertire qualsiasi stringa in qualsiasi codifica nella sua rappresentazione di array di byte quando viene scritta in un file o stream:

 public static class StreamExtensions { public static byte[] ToBytes(this string value, Encoding encoding) { using (var stream = new MemoryStream()) using (var sw = new StreamWriter(stream, encoding)) { sw.Write(value); sw.Flush(); return stream.ToArray(); } } } 

Uso:

 stringValue.ToBytes(Encoding.UTF8) 

Questo funzionerà anche per altre codifiche come UTF-16 che richiede la distinta base.

UTF-8 non richiede una distinta materiali, perché è una sequenza di parole da 1 byte. UTF-8 = UTF-8BE = UTF-8LE.

Al contrario, UTF-16 richiede una distinta materiali all’inizio del stream per identificare se il resto del stream è UTF-16BE o UTF-16LE, perché UTF-16 è una sequenza di parole a 2 byte e la distinta componenti identifica se il i byte nelle parole sono BE o LE.

Il problema non riguarda la class Encoding.UTF8 . Il problema si trova con qualsiasi programma che si sta utilizzando per visualizzare i file.

Ricorda che le stringhe .NET sono tutte unicode mentre rimangono in memoria, quindi se riesci a vedere correttamente il tuo csvString con il debugger il problema è scrivere il file.

Secondo me dovresti restituire un FileResult con la stessa codifica dei file. Prova a impostare la codifica di ritorno del file,