我在C#中的ASP.NET MVC 2应用程序中对UTF8编码有疑问。我正在尝试让用户从字符串下载一个简单的文本文件。我试图通过以下行获得字节数组:

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

但是当我将其退还以供下载时:

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

我得到一个没有BOM的文件,因此我无法正确显示Croatian字符。这是因为我的字节数组在编码后不包括BOM。我triend手动插入这些字节,然后正确显示,但这不是最好的方法。

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

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

有帮助吗?

解决方案

这样尝试:

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

原因是使用Boolean参数的UTF8Encoding构造函数并不能执行您期望的事情:

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

结果数组将包含一个值为97的单个字节。没有BOM,因为UTF8不需要BOM。

其他提示

我创建了一个简单的扩展程序,以将任何编码中的任何字符串转换为字节数组表示为文件或流时的表示:

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

用法:

stringValue.ToBytes(Encoding.UTF8)

这也适用于需要BOM的其他编码,例如UTF-16。

UTF-8不需要BOM,因为它是1字节单词的序列。 UTF-8 = UTF-8BE = UTF-8LE。

相比之下,UTF-16需要在流的开头一个BOM来识别该流的其余部分是UTF-16BE还是UTF-16LE,因为UTF-16是2字节单词的序列,并且BOM是否确定了是否标识单词中的字节是或le。

问题不在于 Encoding.UTF8 班级。问题在于您使用的任何程序来查看文件。

请记住,.NET字符串在存储器中留在存储器中时都是Unicode,因此,如果您可以通过调试器正确看到CSVSTRING,则问题是编写文件。

我认为您应该退还 FileResult 用相同的编码文件。尝试设置返回的文件编码,

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top