gpt4 book ai didi

c# - 从 .NET Core Controller 返回 CSV

转载 作者:可可西里 更新时间:2023-11-01 07:55:18 28 4
gpt4 key购买 nike

我在将 .NET Core API Controller 端点解析为 CSV 下载时遇到问题。我正在使用从 .NET 4.5 Controller 中提取的以下代码:

[HttpGet]
[Route("{id:int}")]
public async Task<HttpResponseMessage> Get(int id)
{
string csv = await reportManager.GetReport(CustomerId, id);
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StringContent(csv);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
response.Content.Headers.ContentDisposition =
new ContentDispositionHeaderValue("attachment") { FileName = "report.csv" };
return response;
}

当我从我的 Angular 4 应用程序访问这个端点时,我收到了写入浏览器的以下响应:

{
"version": {
"major": 1,
"minor": 1,
"build": -1,
"revision": -1,
"majorRevision": -1,
"minorRevision": -1
},
"content": {
"headers": [
{
"key": "Content-Type",
"value": [
"text/csv"
]
},
{
"key": "Content-Disposition",
"value": [
"attachment; filename=11.csv"
]
}
]
},
"statusCode": 200,
"reasonPhrase": "OK",
"headers": [ ],
"requestMessage": null,
"isSuccessStatusCode": true
}

我的预期是,当我到达终点时,系统会提示用户下载 CSV。

我找到了 this发布如何在 .NET Core 中“导出”CSV。问题是我正在从其源(一个 AWS S3 存储桶)中检索内存中的 CSV,而此代码似乎仅在您拥有 IEnumerable<object> 时才有效。 .

我想知道我的问题是出在请求 header 还是响应 header 中,哪里有什么东西阻止浏览器从我的 API 检索 CSV。这是我在浏览器控制台中看到的内容:

enter image description here

最佳答案

解决方案:使用FileResult

如果您希望客户端获得“保存文件”对话框,则应使用此选项。

这里有多种可供选择,比如 FileContentResult , FileStreamResult , VirtualFileResult , PhysicalFileResult ;但它们都派生自 FileResult - 因此我们将在本例中使用它。

public async Task<FileResult> Download()
{
string fileName = "foo.csv";
byte[] fileBytes = ... ;

return File(fileBytes, "text/csv", fileName); // this is the key!
}

The above will also work if you use public async Task<IActionResult> if you prefer using that instead.

The key is that you return a File type.

额外:内容处置

FileResult 会自动向 Content-Disposition 提供正确的 attachment header 。

如果您想在浏览器中打开文件(“内联”),而不是提示“保存文件”对话框(“附件”)。然后您可以通过更改 Content-Disposition header 值来实现。

例如,我们想在浏览器中显示 PDF 文件。

public IActionResult Index()
{
byte[] contents = FetchPdfBytes();
Response.AddHeader("Content-Disposition", "inline; filename=test.pdf");
return File(contents, "application/pdf");
}

归功于此 SO Answer


自定义格式化程序

自定义格式化程序通常是一个不错的选择,因为它们允许客户端请求他们想要的数据类型,例如更流行的 JSON 或不太流行的 XML。

这主要通过提供客户端传递给服务器的 Accept header 中指定的内容来工作,例如 CSV、XLS、XML、JSON 等。

您想使用 "text/csv" 格式类型,但没有为此预定义的格式化程序,因此您必须手动将其添加到输入和输出格式化程序集合中:

services.AddMvc(options =>
{
options.InputFormatters.Insert(0, new MyCustomInputFormatter());
options.OutputFormatters.Insert(0, new MyCustomOutputFormatter());
});

非常简单的自定义格式化程序

这是自定义格式化程序的一个非常简单的版本,它是随 Microsoft Docs example 一起提供的精简版本。

public class CsvOutputFormatter : TextOutputFormatter
{
public CsvOutputFormatter()
{
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/csv"));
SupportedEncodings.Add(Encoding.UTF8);
SupportedEncodings.Add(Encoding.Unicode);
}

protected override bool CanWriteType(Type type)
{
return true; // you could be fancy here but this gets the job done.
}

public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
{
var response = context.HttpContext.Response;

// your magic goes here
string foo = "Hello World!";

return response.WriteAsync(foo);
}
}

强制特定格式

// force all actions in the controller
[Produces("text/csv")]
public class FooController
{
// or apply on to a single action
[Produces("text/csv")]
public async Task<IActionResult> Index()
{
}
}

有关更多信息,我建议您阅读:

关于c# - 从 .NET Core Controller 返回 CSV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46976804/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com