Comment GetBytes () en C# avec UTF8 encoding avec BOM?

J'ai un problème avec L'encodage UTF8 dans mon asp.net mvc 2 application in C#. J'essaie de laisser l'Utilisateur télécharger un simple fichier texte à partir d'une chaîne. J'essaie d'obtenir un tableau d'octets avec la ligne suivante:

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

mais quand je le renvoie pour téléchargement en utilisant:

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

j'obtiens un fichier qui est sans BOM, donc je ne croate caractères affichés correctement. C'est parce que mon tableau d'octets n'inclut pas BOM après encodage. Je triend insérant ces octets manuellement et puis il apparaît correctement, mais ce n'est pas la meilleure façon de le faire.

j'ai aussi essayé de créer une instance de classe UTF8Encoding et de passer une valeur booléenne (true) à son constructeur pour inclure BOM, mais cela ne fonctionne pas non plus.

quelqu'un a une solution? Merci!

42
demandé sur Darin Dimitrov 2010-12-11 02:05:13

4 réponses

Essayez comme ceci:

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");
}

la raison est que le constructeur UTF8Encoding qui prend un paramètre booléen ne fait pas ce à quoi vous vous attendez:

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

le tableau résultant contiendrait un octet simple avec la valeur de 97. Il n'y a pas de BOM parce que UTF8 n'a pas besoin de BOM.

100
répondu Darin Dimitrov 2010-12-10 23:24:54

j'ai créé une extension simple pour convertir n'importe quelle chaîne dans n'importe quel encodage à sa représentation de tableau d'octets quand il est écrit à un dossier ou à un flux:

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();
        }
    }
}

Utilisation:

stringValue.ToBytes(Encoding.UTF8)
6
répondu Hovhannes Hakobyan 2015-06-15 07:28:16

UTF-8 ne nécessite pas de BOM, car il s'agit d'une séquence de mots d'un octet. UTF-8 = UTF-8BE = UTF-8LE.

en revanche, UTF-16 nécessite un BOM au début du flux pour identifier si le reste du flux est UTF-16BE ou UTF-16LE, parce que UTF-16 est une séquence de mots de 2 octets et le BOM identifie si les octets dans les mots sont BE ou LE.

Le problème ne réside pas avec l' Encoding.UTF8 classe. Le problème réside dans le programme que vous utilisez. pour afficher les fichiers.

2
répondu yfeldblum 2010-12-10 23:11:19

rappelez-vous que .net strings sont toutes unicode pendant qu'il reste dans la mémoire, donc si vous pouvez voir votre csvString correctement avec le débogueur le problème est d'écrire le fichier.

À mon avis vous devriez retourner un FileResult avec le même encodage que les fichiers. Essayez de définir l'encodage du fichier de retour,

-2
répondu Daniel Peñalba 2010-12-10 23:12:25