为几个HttpStatusCodes设置一个ProducesResponseType typeof

And*_*res 7 c# http-status-codes asp.net-web-api swagger asp.net-core

我正在设置ProducesResponseType,以便将其记录在Swagger中.

如果响应成功(OK => 200),则会产生IEnumerable.

[ProducesResponseType(typeof(IEnumerable<MyModel>), 200)]
Run Code Online (Sandbox Code Playgroud)

但是当我得到异常时,我会抓住它,然后生成我的自定义APIError类的对象.当我填充对象时,我可以设置不同的HttpStatusCodes,但最后,我想要的是能够设置ProducesResponseType是我所有剩余HttpStatusCodes的APIError类.我的意思是,我可以得到BadRequest,ServerInternalError,Forbidden等,但所有都会有相同的响应类型(ApiError).有没有办法为所有错误http代码设置这行代码?或者我需要逐个设置它?

[ProducesResponseType(typeof(ApiError), ???)]
Run Code Online (Sandbox Code Playgroud)

最终结果应如下所示:

[ProducesResponseType(typeof(IEnumerable<MyModel>), 200)]
[ProducesResponseType(typeof(ApiError), AllFailureHttpCodes)]
Run Code Online (Sandbox Code Playgroud)

Tse*_*eng 11

我担心这是不可能的,至少不是每一个动作.

IApiResponseMetadataProvider(见这里),只有一个单一的int StatusCode { get; }定义的属性和它的用于两个ProducesAttributeProducesResponseTypeAttribute.

但是,在您的特殊情况下,您可以将其注册为全局过滤器,因为无论是GET,POST,PUT还是DELETE,所有操作的错误结果都应相同.

services.AddMvc(options =>
{
    options.Filters.Add(new Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(typeof(ApiError), 400));
    options.Filters.Add(new Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(typeof(ApiError), 401));
    options.Filters.Add(new Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(typeof(ApiError), 409));
});
Run Code Online (Sandbox Code Playgroud)

然后应将这些应用于MVC/WebAPI应用程序中的每个操作.

警告的话

但是,我个人认为这种用法是错误的,因为它会表明你的每个方法都可以处理这些类型的错误.例如409专门用于冲突,在您使用它的WebAPI中,当更新资源时出现错误,即使用乐观并发时,记录被另一个用户更改,因此记录的版本发生了更改,更新失败.

将这些添加到每个方法都是错误的.如果您的操作确实处理了此状态代码,则只应添加状态代码.例如,409仅适用于PUT和POST方法.其中404可能适合GET和PUT(更新),但不太适合POST(插入).

这尤其糟糕,当您使用Swagger等工具生成Api Docs时,您将获得错误的文档.您应该将其ProducesResponseType视为文档的形式,因此,不应该使用过于通用的方法.