Web API操作会返回FileContentResult,如果保存为.csv,将以乱码打开,而如果为.txt,则为ok。 为什么?

我使用ASP.NET Web API通过http获取响应导出文件。 为此,我返回一个FileContentResult对象,如下所示:

return File(Encoding.UTF8.GetBytes(fileContents.ToString()), "text/plain; charset=UTF-8"); 

经过几分钟的编码问题后,我使用谷歌的高级REST客户端来执行获取到网页API控制器的行动,该文件正在下载就好了。

那么,不完全是。 我最初希望它被发送/下载为.csv文件。 如果我将http请求内容types设置为“ text / csv ”而File()调用也将响应的内容types设置为“text / csv”,Advanced REST Client将正确显示内容,但是Excel会打开它作为乱码数据。

如果我只是简单地将内容types改为“ text / plain ”,把它保存为一个.txt文件(保存后必须重命名,不知道为什么要保存为_.text-plain,而作为csv它以.csv扩展名保存),最后在Excel中执行导入,如此处所述的Excel导入文本向导,然后Excel将正确打开文件。

为什么.csv被打开为乱码,而.txt不是? 对于打开.csv,没有像.txt文件一样的导入向导(不是我所知道的)。

在下面提供一些源代码:

 StringBuilder fileContents = new StringBuilder(); //csv header fileContents.AppendLine(String.Join(CultureInfo.CurrentCulture.TextInfo.ListSeparator, fileData.Select(fileRecord => fileRecord.Name))); //csv records foreach (ExportFileField fileField in fileData) fileContents.AppendLine(fileField.Value); return File(Encoding.UTF8.GetBytes(fileContents.ToString()), "text/plain; charset=UTF-8"); 

根据要求,这两个文件的二进制内容。 文本纯文本(.txt)版本(将在Excel中打开,使用导入):

和.csv之一(excel将用垃圾数据打开的那个):

(文件是一样的,截屏的裁剪是不一样的…)

我能够通过使用BOM保存包含希腊字符的文件来重现此问题。 双击尝试使用系统的语言环境(希腊语)导入文件。 手动导入时,Excel检测到代码页并提供使用65001(UTF8)代码页。

这种行为是奇怪的,不是一个错误。 文本文件不包含有助于检测其代码页的指示,也无法猜测。 仅包含保存为1252的AZ字符的ASCII文件与使用1253保存的ASCII文件相同。这就是Windows使用系统代码页的原因,系统代码页是用于所有非Unicode程序文件的本地代码页。

当您双击文本文件时,Excel不会要求您input正确的编码 – 这可能会很快变得乏味。 而是使用您的区域设置和系统代码页打开文件。 在您的机器上创build的ASCII文件使用您的系统的代码页保存,所以这种行为是合乎逻辑的。 非程序员给你的文件也可能使用你国家的代码页保存。 程序员通常把所有东西都切换到美国英语,这就是问题的出发点。 您的REST客户端可能使用大多数程序员使用的拉丁编码将文本保存为ASCII。

当您将文本文件导入到空白工作表时,Excel可以询问您要执行的操作。 它尝试通过检查可能与文件内容匹配的BOM或代码页来检测代码页,并在导入对话框中显示猜测以及预览。 小数点和列分隔符仍然是由您的区域设置提供的(不能猜测那些)。 UTF8通常很容易猜到 – 文件以BOM开头或包含NUL条目。

ASCII码页面虽然很难。 将我的希腊文件保存为ASCII会导致日文猜测。 我想这对你来说是英文的幽默。

令我惊讶的是,试图通过浏览器执行请求, 而不是使用谷歌的高级REST客户端 ,点击下载的文件正常工作! Excel正确打开它。 所以这个问题一定要用ARC。

在任何情况下,由于该过程不会使用除浏览器以外的http客户端…我的问题已经消失。 再次,在ARC的输出屏幕上文件显示正确。 我不知道为什么点击它在Excel中打开它“被损坏”。

奇怪。

该文件的二进制内容显示正确的UTF-8编码的CSV文件与希伯来字符。 如果您在注释中声明,Excel不允许您在打开CSV文件时更改其猜测的文件编码,这相当于Excel本身的错误行为(如果需要,请将其称为错误)。

您的select是:使用LibreOffice( http://www.libreoffice.org/ ),电子表格组件允许您自定义打开CSV文件的设置。

另一个是写一个小程序明确地将您的文件转换为Excel所期望的编码 – 如果您安装了Python3解释器,则可以键入以下内容:

python -c "open('correct.csv', 'wt', encoding='cp1255').write(open('utf8.csv', encoding='utf8').read())"

然而,如果你的默认Windows编码不是cp1255来处理希伯来语,正如我上面所说的那样,这不会帮助excel,但给你不同的乱码:-)在这种情况下,你应该求助于使用程序,可以正确处理不同的编码。

(注意,在Windows中有一个Python调用返回默认的系统编码,但是我忘记了它是什么,并且不容易被googleable)