c# - 带编码的 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
为文件对象结果然后导出为文件对象时会丢失编码。
对此问题的任何帮助将不胜感激。
解决方案
因此,一旦我将内容类型从text/csv
更改application/octet-stream
为如下:
return File(stream, "application/octet-stream", "AllCountries.csv");
它突然像一个魅力。
推荐阅读
- css - 视频应触及盒子的顶部和底部
- firebase - Firestore 安全规则 - 获取集合时 {wildcard} 既不为空也不为空
- c - 将 2D 数组转换为 3D?
- sql - 从一列中选择所有值组合
- maven - 为 MariaDB 连接器 J 运行 mvn 测试时如何将 shell 变量或环境变量传递给 Maven
- r - 如何强制 data.table 将 i 中的名称解释为调用环境中的向量?
- c# - 创建倒计时时钟
- java - 如何在jsp中使用JSONArray变量
- javascript - 函数在代码大战中返回类型错误,不知道为什么
- node.js - 使用 gmail 使用 nodemailer 的最佳方式是什么?