I am setting the ProducesResponseType so as to have it documented with Swagger.
If the response is succesful (OK => 200), then it produces a IEnumerable.
[ProducesResponseType(typeof(IEnumerable<MyModel>), 200)]
But when I get an exception, I catch it, and then generate an object of my custom APIError class. When I populate the object, I can set different HttpStatusCodes, but in the end, what I want is to be able to set that ProducesResponseType is my APIError class for all the remaining HttpStatusCodes. I mean, I can get BadRequest, ServerInternalError, Forbidden, etc, but all are going to have the same response type (ApiError). Is there any way to set this line of code for all the error http codes? Or do I need to set it one by one?
[ProducesResponseType(typeof(ApiError), ???)]
Final result should look like this:
[ProducesResponseType(typeof(IEnumerable<MyModel>), 200)]
[ProducesResponseType(typeof(ApiError), AllFailureHttpCodes)]
I fear that's not possible, at least not per action.
The IApiResponseMetadataProvider
(see here) only has a single int StatusCode { get; }
property defined and it's used for both ProducesAttribute
and ProducesResponseTypeAttribute
.
However, in your special case you may be able to register it as a global filter though, since the error result should be same on all actions no matter if it's GET, POST, PUT or 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));
});
These should then be applied to every action in your MVC/WebAPI application.
However, personally I find this usage wrong, because it would signal that every of your method can handle these type of errors. For example 409 is specifically for conflict, in a WebAPI you use it, when there is an error with updating an resource i.e. when using optimistic concurrency, the record was changed by another user and, hence the version of the record was changed and update failed.
Adding these to every method is just wrong. You should only add a status code if your action really handles this status code. For example, 409 is only suitable with PUT and POST Methods. Where 404 may be suitable for GET and PUT (update), but less suitable for POST (inserts).
This is especially bad, when you use tools such as Swagger to generate Api Docs, then you will just get a wrong documentation. You should look at ProducesResponseType
as form of documentation and as such, shouldn't use a too generic approach for it.
With ASP.NET Core 2.2 the Swagger API support was greatly improved, this also includes convention based response type and codes.
It already comes with a good set of default conventions, but you can also override it and provide your own convention methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With