提问人:Beli 提问时间:6/22/2023 更新时间:6/23/2023 访问量:161
不清楚为什么此 Swagger UI 仅针对此特定属性失败并出现“FormatterNotFoundException”异常
Unclear why this Swagger UI fails with 'FormatterNotFoundException' exception only for this specific property
问:
如何使示例在 Swagger 中工作,同时在控制器方法中仍然具有 [Produces(“application/json”, “application/xml”)] 定义。
在 .Net Core 6 API 中,已将 Swagger 与 Swashbuckle.AspNetCore.Filters 一起设置,并且可以在 Swagger UI 页中查看请求和响应示例。 为了支持 XML 格式,在程序 .cs 中设置了序列化程序
builder.Services.AddControllers(options =>
{
options.InputFormatters.Add(new XmlSerializerInputFormatter(options));
options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
});
这在swagger.json生成失败之前效果很好,出现以下错误
Swashbuckle.AspNetCore.Filters.MvcOutputFormatter+FormatterNotFoundException:找不到“application/xml; charset=utf-8”的 OutputFormatter
经分析发现,该问题是由返回特定响应类型的控制器方法之一引起的。该对象不是超级复杂且相对简单的类型,可生成如下所示的 resposne json
{
"acceptedRequests": [
{
"requestId": "7F8092B1-F712-46E7-B991-8D8AEFC3310A",
"dataAcceptanceStamp": 1687407503,
"totalDataFilesCount": 3,
"totalRecordCount": 1674
}
],
"erroredData": [
{
"requestId": "56100665-AF7D-4663-A52E-7D688A5432F6",
"totalDataFilesCount": 2,
"receivedFilesCount": 2,
"processedFilesCount": 1,
"errors": {
"statusCode": 422,
"message": "xyz.dat has multiple validation errors",
"errors": {
"key1": "error desc 1",
"key2": "error desc 2"
}
}
}
],
"yetToBeProcessedRequestIds": [
"G6100665-AF7D-4663-A52E-7D688A5432F6"
]
}
下面提供了导致swagger.json失败的控制器方法的定义,问题是由于 SeekApprovalResponse 类型造成的,更具体地说,仅当“Produces”包含“application/xml”时。
[Route("seek/approval")]
[HttpPost]
[Produces("application/json", "application/xml")]
[SwaggerResponse(StatusCodes.Status200OK, Type = typeof(SeekApprovalResponse))]
public async Task<IActionResult> SeekRequestApproval([FromBody] SeekApprovalRequest requests)
{
return Ok(new SeekApprovalResponse());
}
目前尚不清楚是什么让这种“SeekApprovalResponse”类型变得特别,而其他类似的类型工作得很好。
下面提供了此类型的定义以及此类型所需的其他类型
public class SeekApprovalResponse
{
public ProcessedRequests[] AcceptedRequests { get; set; }
public ErrorsInRequest[] ErroredData { get; set; }
public string[] YetToBeProcessedRequestIds { get; set; }
}
{
public class ProcessedRequests
{
public string RequestId { get; set; }
public long DataAcceptanceStamp { get; set; }
public byte TotalDataFilesCount { get; set; }
public uint TotalRecordCount { get; set; }
}
}
public class ErrorsInRequest
{
public string RequestId { get; set; }
public byte TotalDataFilesCount { get; set; }
public byte ReceivedFilesCount { get; set; }
public byte ProcessedFilesCount { get; set; }
public ErrorResponse Errors { get; set; }
}
public class ErrorResponse
{
public int StatusCode { get; set; }
public string Message { get; set; }
public Dictionary<string, string> Errors { get; set; }
}
下面提供了 Swagger Example 类(与上面提供的 json 匹配)
public class SeekApprovalResponseExample : IMultipleExamplesProvider<SeekApprovalResponse>
{
public IEnumerable<SwaggerExample<SeekApprovalResponse>> GetExamples()
{
yield return SwaggerExample.Create(
"Partially approved",
new SeekApprovalResponse()
{
AcceptedRequests = new ProcessedRequests[]
{
new ProcessedRequests
{
RequestId = "7F8092B1-F712-46E7-B991-8D8AEFC3310A",
DataAcceptanceStamp = 1687407503,
TotalDataFilesCount = 3,
TotalRecordCount = 1674
}
},
ErroredData = new DataErrorRSDE001[]
{
new DataErrorRSDE001
{
RequestId = "56100665-AF7D-4663-A52E-7D688A5432F6",
TotalDataFilesCount = 2,
ReceivedFilesCount = 2,
ProcessedFilesCount = 1,
Errors = new ErrorResponse
{
StatusCode = 422,
Message = "xyz.dat has multiple validation errors",
Errors = new Dictionary<string, string>
{
{"key1", "error desc 1"},
{"key2", "error desc 2"}
}
}
}
},
YetToBeProcessedRequestIds = new string[] { "G6100665-AF7D-4663-A52E-7D688A5432F6" }
}
);
}
}
删除“application/xml”后,Swagger UI 将按预期工作,按预期显示 json 示例,表明错误没有误导性。 当“application/xml”被添加回“Produces”时,戳了 SeekApprovalResponse 类型,似乎 ErrorResponse 类中的公共 Dictionary<string, string> 错误给格式化程序带来了麻烦。暂时删除该属性后,将创建swagger.json,并且页面显示正常。如何让 Dictionary<string, string> 属性与 Swagger UI 一起使用?
答:
您没有启用 XML 格式化程序。请将以下代码行添加到 Program.cs:
builder.Services.AddControllers().AddXmlDataContractSerializerFormatters();
评论