如何在带有BOM的UTF8编码的C#中使用GetBytes()?

Neb*_*ron 45 asp.net-mvc encoding byte-order-mark utf-8

我在C#中的asp.net mvc 2应用程序中遇到UTF8编码问题.我正在尝试让用户从字符串下载一个简单的文本文件.我试图用以下行获取字节数组:

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

但当我使用以下命令返回下载时:

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

我得到一个没有BOM的文件,所以我没有正确显示克罗地亚字符.这是因为我的bytes数组在编码后不包含BOM.我手动插入这些字节然后它正确显示,但这不是最好的方法.

我还尝试创建UTF8Encoding类实例并将布尔值(true)传递给其构造函数以包含BOM,但它也不起作用.

有人有解决方案吗?谢谢!

Dar*_*rov 118

试试这样:

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");
}
Run Code Online (Sandbox Code Playgroud)

原因是采用布尔参数的UTF8Encoding构造函数不能达到预期效果:

byte[] bytes = new UTF8Encoding(true).GetBytes("a");
Run Code Online (Sandbox Code Playgroud)

生成的数组将包含一个值为97的单个字节.没有BOM,因为UTF8不需要BOM.

  • 没有BOM,因为`GetBytes`不能假设我们正在写一个文件.写入文件的人应首先执行前导码(例如,像StreamWriter). (6认同)
  • 谢谢!我的疯狂与我的特殊字符不在Excel CSV :) (2认同)
  • 为了清楚起见,Encoding.UTF8等效于new UTF8Encoding(true)。该参数控制`GetPreamble()`是否发出BOM。 (2认同)
  • 为什么内容类型设置为“application/csv”而不是“text/csv”(如图所示[此处](http://www.freeformatter.com/mime-types-list.html))?无论如何,这两种方法都不起作用,在这里。Excel 仍然使用无法识别的字符打开它。 (2认同)

小智 10

我创建了一个简单的扩展,将任何编码中的任何字符串转换为字节数组的表示形式,当它被写入文件或流时:

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

stringValue.ToBytes(Encoding.UTF8)
Run Code Online (Sandbox Code Playgroud)

这也适用于需要BOM的UTF-16等其他编码.