通过.Net Web API下载后,Csv文件不显示德语字符

dz6r00yl  于 2022-12-20  发布在  .NET
关注(0)|答案(2)|浏览(153)

我必须返回一个csv文件模板,其中有一些列与德国字符在我的一个API端点。
这是端点的简化版本:

[HttpGet]
    [ProducesResponseType(typeof(Stream), StatusCodes.Status200OK)]
    [Route("template")]
    public async Task GetTemplate()
    {
        Response.StatusCode = StatusCodes.Status200OK;
        Response.ContentType = "text/csv";
        Response.Headers.AddContentDispositionAttachment("Template.csv");

        CsvConfiguration csvConfiguration = new (new CultureInfo("de-de"))
        {
            Delimiter = ";",
            HasHeaderRecord = false
        };

        string header = $"Url;Beschreibung;Code;ID;Löschen;Straße;Pünklitch";

        using var streamWriter = new StreamWriter(Response.Body, Encoding.UTF8, 65536);
        await using var csvWriter = new CsvWriter(streamWriter, csvConfiguration);
        await streamWriter.WriteAsync(header);
    }

这是非常直接的。
问题是;当我调用端点通过swagger在本地或在服务器上下载文件 * 它不显示德语字符正确 *。此外,当我entagrate端点到我的前端和下载文件通过用户界面它也表现相同的方式,不显示德语字符。但当我 * 调用端点从浏览器直接一切看起来正常 *。
这是下载后csv文件的外观:

有什么想法吗?我怎样才能修复编码问题?
我使用的是.net framwork 6

zbsbpyhn

zbsbpyhn1#

问题是,当您双击CSV文件以在Excel中打开它时,Excel会假定该文件使用的是较旧的Windows编码,而不是UTF8。您有两个选项:
1.强制字节顺序标记(BOM)位于UTF8文件的开头。大多数较新版本的Excel将识别BOM,并将其作为UTF8而不是旧编码打开。但是,某些版本的Excel将忽略BOM。(仅供参考,您的代码没有使用csvWriter,但当您直接使用csvWriter而不是streamWriter进行输出时,这应该仍然有效。)

using var streamWriter = new StreamWriter(Response.Body, Encoding.UTF8, 65536);
using var csvWriter = new CsvWriter(streamWriter, csvConfiguration);

var preamble = Encoding.UTF8.GetPreamble();
await streamWriter.BaseStream.WriteAsync(preamble, 0, preamble.Length);

await streamWriter.WriteAsync(header);

1.使用旧的Windows编码代替UTF8。只要您只有德语字符而没有其他无法转换的UTF8字符,这应该可以工作。我不确定在德国会是什么,但我猜它是Windows-1252。

using var streamWriter = new StreamWriter(Response.Body, Encoding.GetEncoding(1252), 65536);

// Or you might need to use iso-8859-1
using var streamWriter = new StreamWriter(Response.Body, Encoding.GetEncoding("iso-8859-1"), 65536);
qyswt5oh

qyswt5oh2#

你可以定制一个Ascii转换器,用一个ascii符号替换你所有的字符。例如,你可以使用Dictionary<string, string>并将每个字符Map到它的ascii

private Dictionary<string, string> CharToASCII = new Dictionary<string, string>() {
    {"Ö",  @"\'d6"},
    {"ö",  @"\'f6"}
    }

然后你可以用你的字符串作为输入参数调用一个函数,结果你会得到一个ASCII而不是德语字母

public string ConvertToAscii(string myString)
        {

            var res = CharToASCII.Aggregate(myString, (current, value) =>
                current.Replace(value.Key, value.Value));

            return res;
        }

相关问题