【发布时间】:2021-08-08 20:29:29
【问题描述】:
我正在使用 Net 5.0。 我为 ObjectResult 添加了自定义输出格式化程序。
var result = new ObjectResult(list)
{
StatusCode = (int)HttpStatusCode.OK
};
result.Formatters.Add(new ExcelOutputFormatter());
return result;
但现在它会为每个请求返回我的自定义输出,无论我向 Accept Header 写什么。
如果我不添加自定义输出格式化程序,我希望保留 */* 以返回它的结果。
就我而言,我希望 application/json 类似于默认值,并且仅将我的格式化程序用于 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet。
我找到了 XmlSerializerOutputFormatter,我可以在我的格式化程序之前添加它,这样它就返回 XML 作为默认值,而我的 excel 只返回指定的标题。但我没有找到可行的 JSON 格式化程序。我正在使用一些默认的 .net 核心格式化程序,我没有在 Startup.cs 中添加任何格式化程序。
这是我的输出格式化程序
public class ExcelOutputFormatter : OutputFormatter
{
public ExcelOutputFormatter()
{
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
}
protected override bool CanWriteType(Type type)
{
return typeof(IEnumerable<Person>).IsAssignableFrom(type);
}
public override Task WriteResponseBodyAsync(
OutputFormatterWriteContext context)
{
var httpContext = context.HttpContext;
var serviceProvider = httpContext.RequestServices;
var logger = serviceProvider.GetRequiredService<ILogger<ExcelOutputFormatter>>();
var persons = context.Object as IEnumerable<Person>;
var workbook = new ClosedXML.Excel.XLWorkbook();
workbook.Worksheets.Add("Test");
workbook.SaveAs(httpContext.Response.Body);
return Task.CompletedTask;
}
}
【问题讨论】:
-
在
WriteResponseBodyAsync中添加一些解析怎么样?检查context.HttpContext.Request.Headers中的 Accept Header 并根据它执行不同的操作? -
我想使用格式化程序,所以我不需要自己检查标题。如果我添加多个格式化程序,则每个仅针对它的类型调用,如果无法确定任何匹配项,则使用第一个添加的。但我希望它会使用某种全局设置,因为其他控制器在没有指定任何内容的情况下返回 json。
-
如果您添加一个格式化程序,它们会按顺序进行评估。如果
CanWriteType匹配,它将始终被使用。因此,您必须始终自己添加支票。 -
我无法检查 CanWriteType 中的 Accept 标头以返回 false。如果我将文本/纯文本写入接受,我的格式化程序也会被调用。也许有一种方法可以获取默认用于控制器的格式化程序列表并将其添加到我的 ObjectResult 格式化程序列表中?
-
我的问题类似,但略有不同。我在 services.AddControllers 注册中添加了我的自定义格式化程序。
lang-c# services.AddControllers(options => { options.RespectBrowserAcceptHeader = true; options.OutputFormatters.Add(new CsvOutputFormatter()); })我发现 Accept 标头受到尊重,一切都按预期工作。但是 - 如果未提供 Accept 标头,则默认为自定义格式化程序。希望默认为 application/json 格式化程序
标签: c# json asp.net-core asp.net-core-webapi .net-5