.NET Core WebAPI 内容协商

3
我正在尝试为我的.NET Core 1.1 WebApi添加CSV输出格式化程序。
我已经安装了WebAPIContrib.Core软件包(https://github.com/damienbod/WebAPIContrib.Core/tree/master/src/WebApiContrib.Core.Formatter.Csv)。
我的Startup现在看起来像这样:
var csvFormatterOptions = new CsvFormatterOptions();
services.AddMvcCore(options =>
{
    options.OutputFormatters.Add(new CsvOutputFormatter(csvFormatterOptions));
    options.FormatterMappings.SetMediaTypeMappingForFormat("csv", MediaTypeHeaderValue.Parse("text/csv"));
})
.AddJsonFormatters()
.AddJsonOptions(options => new SerializationHelper().Configure(options.SerializerSettings));

我的控制器方法是完全通用的,看起来像这样

[HttpGet("/api/export")]
[Produces("text/csv")]
public async Task<List<Data>> GetDataAsCsv()
{
    return await _someService.GetData();
}

我的问题是,如果我删除了produces属性并且没有发送accept头部,我仍然可以收到一个CSV文件。他怎么知道要返回一个CSV文件呢?我的其他方法仍然会生成JSON,这应该是正确的方式,只是我不明白为什么会这样,我担心这会在后面导致问题。
1个回答

1

内容协商是框架的一部分,但你需要更新操作以利用它。

[HttpGet("/api/export")]
public async Task<IActionResult> GetData() {
    List<Data> data = await _someService.GetData();
    return Ok(data); // <-- returns OkObjectResult with content negotiation baked in
}

引用原帖中的repo链接,查看以下来自其文档的内容:

Get方法使用HTTP请求中的Accept头导出数据。默认情况下,将返回Json。如果将Accept头设置为“text/csv”,则将以csv格式返回数据。由于使用了Produces属性,因此GetDataAsCsv方法始终返回csv数据。

// GET api/csvtest
[HttpGet]
public IActionResult Get() {
    return Ok(DummyData());
}

[HttpGet]
[Route("data.csv")]
[Produces("text/csv")]
public IActionResult GetDataAsCsv() {
    return Ok( DummyData());
}

正如文档中所指示的那样,您应该确保在启动时正确配置它。

默认情况下,ASP.NET Core只有Json(可能还有纯文本)作为内容类型。

var csvOptions = new CsvFormatterOptions();
services.AddMvcCore(options => {
        options.RespectBrowserAcceptHeader = true;
    })
    .AddJsonFormatters()
    .AddJsonOptions(options => new SerializationHelper().Configure(options.SerializerSettings))
    .AddCsvSerializerFormatters(csvOptions);

注意,默认情况下调用 RespectBrowserAcceptHeader 的值为false,因此如果您想进行内容协商,必须启用此选项。
参考 ASP.NET Core中的内容协商

我不想使用AddMvc,因为它是一个WebApi,而我不需要Razor。AddMvcCore可以完全做到同样的事情,我只需要指定我想要添加的服务即可。我的问题是,如果我指定接受头并删除产生属性,我仍然会得到一个CSV,这对我来说毫无意义。 - Narcil
尝试添加返回Ok(_someService.GetData())并没有改变任何东西。我仍然得到一个没有produces属性和没有接受头的csv文件。 - Narcil
检查您添加格式化程序的顺序。同时显示返回JSON的一个实例。 - Nkosi
@Narcil,你也可以看一下我找到的这篇文章:https://wildermuth.com/2016/03/16/Content_Negotiation_in_ASP_NET_Core - Nkosi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接