首页 > 解决方案 > 带编码的 Asp net core 文件结果

问题描述

我正在尝试从我的 ASP.Net Core 3.1 Web API 导出简单的 CSV 文件。为此,我使用 CsvHelper 包,在其中使用以下方法生成 MemoryStream:

public async Task<MemoryStream> ExportAsync(IEnumerable records)
{
    byte[] content = null;
    using (var mem = new MemoryStream())
    using (var writer = new StreamWriter(mem, Encoding.GetEncoding("windows-1250")))
    {
        using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
        {
            csvWriter.Configuration.TypeConverterOptionsCache.GetOptions<DateTime>().Formats = new[] { "yyyy-MM-dd HH:mm:ss" };
            csvWriter.Configuration.Delimiter = "|";
            csvWriter.WriteField("sep=|", false);
            csvWriter.NextRecord();
            await csvWriter.WriteRecordsAsync(records).ConfigureAwait(false);
            await csvWriter.FlushAsync().ConfigureAwait(false);
            await writer.FlushAsync().ConfigureAwait(false);
            content = mem.ToArray();
        }
    }

    var output = new MemoryStream(content);
    return output;
}

这是通过以下方法从我的控制器调用的:

[HttpGet("GetCountriesAsCSV")]
[SwaggerResponse(400, typeof(string))]
[SwaggerResponse(typeof(File))]
public async Task<IActionResult> GetCountriesAsCSV()
{
    try
    {
        var allCountries = await countryManager.GetAllAsync();
        var transformedCountries = mapper.Map<IEnumerable<CountryCsv>>(allCountries);
        var stream = await csvExportService.ExportAsync(transformedCountries).ConfigureAwait(false);

        return File(stream, "text/csv", $"AllCountries{DateTime.Now.Ticks}.csv");
    }
    catch (Exception ex)
    {
        return StatusCode((int)HttpStatusCode.BadRequest, ex.Message);
    }
}

问题是,当我从 Excel 打开导出的 CSV 文件时,特殊字符无法正确显示(由于编码)。这是输出的样子:

在此处输入图像描述

我尝试使用完全相同的方法来生成 CSV 文件,但我没有将其推回为MemoryStream,而是将文件直接保存在当前文件夹中,如下所示:

private async Task WriteAll(IEnumerable records)
{
    using (var writer = new StreamWriter("RobertFile.csv", true, Encoding.GetEncoding("windows-1250")))
    {
        using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
        {
            csvWriter.Configuration.TypeConverterOptionsCache.GetOptions<DateTime>().Formats = new[] { "yyyy-MM-dd HH:mm:ss" };
            csvWriter.Configuration.Delimiter = "|";
            csvWriter.WriteField("sep=|", false);
            csvWriter.NextRecord();
            await csvWriter.WriteRecordsAsync(records).ConfigureAwait(false);
            await csvWriter.FlushAsync().ConfigureAwait(false);
            await writer.FlushAsync().ConfigureAwait(false);
        }
    }
}

如您所见,ExportAsync与此WriteAll方法之间的唯一区别是StreamWriter参数(然而,具有完全相同的编码规范)。

打开此文件后,它看起来非常好,如下所示:

在此处输入图像描述

我不太明白,为什么在转换MemoryStream为文件对象结果然后导出为文件对象时会丢失编码。

对此问题的任何帮助将不胜感激。

标签: c#encodingasp.net-core-webapiexport-to-csvasp.net-core-3.1

解决方案


因此,一旦我将内容类型从text/csv更改application/octet-stream为如下:

return File(stream, "application/octet-stream", "AllCountries.csv");

它突然像一个魅力。


推荐阅读