我希望我的c#MVC控制器将结果从我的存储库流式返回到CSV。
我已经看到了一些使用FileResult
的例子,但是这些方法似乎依赖于作为字节数组保存在内存中的文件的整个内容。我正在处理的CSV可能会很大,我希望通过直接流式传输来避免将它们存储在内存中。
这个答案展示了两个例子。我首先实现了我的端点,将记录流式传输到端点:
[HttpGet("download")]
public async IAsyncEnumerable<Foo> StreamDownload() {
IAsyncEnumerable<Foo> foos = fooRepository.getAll();
await foreach(Foo foo in foos) {
yield return convertToDto(foo);
}
}
然而,当尝试使用本指南创建自定义格式化程序时,我发现HttpResponses现在使用PipeWriter来处理它们的I/O连接。
我正在尝试创建一个自定义格式化程序,它将从IAsyncEnumerable读取并写入PipeWriter。然而,由于这是一个常见的问题,我认为值得检查一下:
- 这是正确的方法吗
- 是否已经存在类似的转换器?(我找不到(
- 在创建此转换器时,是否还有其他指南/示例值得一看
我能够使用这个NuGet包来处理CSV序列化:https://www.nuget.org/packages/WebApiContrib.Core.Formatter.Csv/
只需将序列化程序添加到服务:
var csvOptions = new CsvFormatterOptions {
UseSingleLineHeaderInCsv = true,
CsvDelimiter = ",",
IncludeExcelDelimiterHeader = true
};
services.AddMvc().AddCsvSerializerFormatters(csvOptions);
并将该方法标记为返回CSV:
[HttpGet("download")]
[Produces("text/csv")]
public async IAsyncEnumerable<Foo> StreamDownload() {
IAsyncEnumerable<Foo> foos = fooRepository.getAll();
await foreach(Foo foo in foos) {
yield return convertToDto(foo);
}
}