im1*_*ike 15 c# csv asp.net asp.net-core
我无法将.NET Core API Controller端点解析为CSV下载.我正在使用以下从.NET 4.5控制器中提取的代码:
[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;
}
Run Code Online (Sandbox Code Playgroud)
当我从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
}
Run Code Online (Sandbox Code Playgroud)
我的期望是,当我点击端点时,将提示用户下载CSV.
我发现这篇文章介绍了如何在.NET Core中"导出"CSV.问题是我正在从它的源(AWS S3存储桶)中检索CSV内存,而这个代码似乎只有在你有一个时才能工作IEnumerable<object>
.
我想知道我的问题是在请求还是响应标头中,哪里有阻止浏览器从我的API检索CSV的东西.这是我在浏览器控制台中看到的内容:
Sve*_*vek 15
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!
}
Run Code Online (Sandbox Code Playgroud)
public async Task<IActionResult>
如果你喜欢使用它,上面也可以使用.关键是你返回一个
File
类型.
该FileResult
会自动提供正确的Content-Disposition
头attachment
.
如果要在浏览器中打开文件("内联"),而不是提示"保存文件"对话框("附件").然后,您可以通过更改Content-Disposition
标头值来实现.
例如,我们想PDF
在浏览器中显示该文件.
public IActionResult Index()
{
byte[] contents = FetchPdfBytes();
Response.AddHeader("Content-Disposition", "inline; filename=test.pdf");
return File(contents, "application/pdf");
}
Run Code Online (Sandbox Code Playgroud)
相信这个SO答案
自定义格式化程序通常是一个很好的选择,因为它将允许客户端询问他们想要数据的类型,例如更流行的JSON或不太流行的XML.
这主要通过提供Accept
客户端传递给服务器的标头中指定的内容来工作,例如CSV,XLS,XML,JSON等.
由于您使用的格式类型"text/csv"
- 当前,当您使用预先捆绑的选项(如FileResult
...)时,没有输入/输出格式化器.因此,您必须将其添加,如下所示:
services.AddMvc(options =>
{
options.InputFormatters.Insert(0, new MyCustomInputFormatter());
options.OutputFormatters.Insert(0, new MyCustomOutputFormatter());
});
Run Code Online (Sandbox Code Playgroud)
这是一个非常简单的自定义格式化程序版本,它是随Microsoft Docs示例提供的精简版本.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
// 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()
{
}
}
Run Code Online (Sandbox Code Playgroud)
有关更多信息,我建议您阅读:
这个问题的新手请看 Svek 的回答。最初的问题是关于 http Content-Disposition
,但看起来搜索引擎在这里发送通用的 .net core csv 查询。Svek 的回答很好地概述了 .Net Core 可用于从控制器返回 CSV 数据的工具。
强制下载文件而不是内联显示的正确方法是使用Content-Disposition
响应标头。虽然以下解决方案有效(请参阅文档),但有人指出这可能会产生意想不到的副作用。
将Content-Type
响应头设置为application/octet-stream
将强制大多数主要浏览器提示用户保存文件而不是在窗口中显示它。
尝试做这样的事情:
var result = new FileContentResult(myCsvByteArray, "application/octet-stream");
result.FileDownloadName = "my-csv-file.csv";
return result;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
16685 次 |
最近记录: |