Open OculiViridi opened 5 years ago
I think you can implement an own attribute which inherits from ProducesResponseType and exposes a Description property for now
For this we need to improve this code here: https://github.com/RSuter/NSwag/blob/86e06e49b529fef46e9683e75aa07ff1a7383837/src/NSwag.SwaggerGeneration/Processors/OperationResponseProcessorBase.cs#L98
=> read from xml docs <response>
or something else...
But replacing ProducesResponseType with SwaggerResponse should work...
@RSuter
But replacing ProducesResponseType with SwaggerResponse should work...
It works! Thanks!
This is my adjusted code, based on the previous sample.
[Authorize]
[ApiVersion("1.0")]
[Produces("application/json")]
[SwaggerTag("Anomalies", Description = "Anomalies management.")]
public class AnomaliesController : BaseController
{
/// <summary>
/// Find anomaly by ID
/// </summary>
/// <param name="id">ID of the anomaly to return</param>
/// <response code="200">Successful operation</response>
/// <response code="400">Invalid ID supplied</response>
/// <response code="404">Anomaly not found</response>
[HttpGet("{id:long}")]
[SwaggerResponse(HttpStatusCode.OK, typeof(api.Anomaly), Description = "Successfull operation")]
[SwaggerResponse(HttpStatusCode.BadRequest, typeof(ProblemDetails), Description = "Invalid ID supplied")]
[SwaggerResponse(HttpStatusCode.NotFound, typeof(ProblemDetails), Description = "Anomaly not found")]
public async Task<ActionResult<api.Anomaly>> Get(long id)
{
return Mapper.Map<api.Anomaly>(await Mediator.Send(new GetAnomalyByIdQuery() { Id = id }));
}
}
Note: ProblemDetails
object is the ASP.NET Core implementation of RFC 7807 Problem Details for HTTP APIs, so it is a standard object that can be used to manage errors.
I'm using the following code in my example project under https://github.com/SeppPenner/NetCoreMQTTExampleIdentityConfig:
/// <summary>
/// Gets the claim by id. GET "api/claim/5".
/// </summary>
/// <param name="claimId">
/// The claim identifier.
/// </param>
/// <returns>
/// The <see cref="Task"/>.
/// </returns>
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "Reviewed. Suppression is OK here.")]
[HttpGet("{claimId}")]
[SwaggerResponse(HttpStatusCode.OK, typeof(DtoReadUserClaim), Description = "Claim found.")]
[SwaggerResponse(HttpStatusCode.NotFound, typeof(int), Description = "Claim not found.")]
[SwaggerResponse(HttpStatusCode.InternalServerError, typeof(string), Description = "Internal server error.")]
[ProducesResponseType(typeof(DtoReadUserClaim), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(int), StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(string), StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<DtoReadUserClaim>> GetClaimById(long claimId)
{
\\ ...
}
which renders to:
The red circles show the stuff that is missing:
Find pet by id
Returns a single pet
ID of the pet to return
How can I get this to work?
P.S. The controller description works as excpected:
The red circles show the stuff that is missing:
- Summary for the method, e.g.
Find pet by id
- Summary for the return value, e.g.
Returns a single pet
- Documentation of the parameter, e.g.
ID of the pet to return
How can I get this to work?
P.S. The controller description works as excpected:
The same happened to me when moved to v12 and now on v13 of NSwag.
The same happened to me when moved to v12 and now on v13 of NSwag.
I don't remember when this happend, but I'm using the latest version of NSwag for sure.
This happens if you use the version 3 of Swagger (AddOpenApiDocument()
method) as well.
I'm using NSwag 13.0.6, and it is using the XMLDOC markup, where the <summary />
tag gets written as the method sumary, the <returns />
tag gets written to the default successful response value, <remarks />
tag forms the body of the documentation, and <param name="" />
tags populate the parameter descriptions. You'll need to make sure you project is set to write the XML output, and NSwag seems to pick that up automatically. That covers most scenarios; the only place it currently falls down is writing a description for non-default return status codes (e.g. 404, 401), and providing example request/response bodies.
So in @SeppPenner 's case, you've got all the above, apart from the <remarks />
tag, so I'm guessing you don't have the <DocumentationFile />
property set in your .csproj
So in @SeppPenner 's case, you've got all the above, apart from the
tag, so I'm guessing you don't have the property set in your .csproj
Ah, this might be the case... I will check that.
You can use the <response code=“...”>...
xml docs tags to specify the response texts.
Thanks @RicoSuter that works a treat.
For example, the following endpoint:
/// <summary>
/// Get employee
/// </summary>
/// <param name="id">The identifier of the employee that should be returned.</param>
/// <returns>
/// Returns the specified employee, if it exists and the current user has access to it.
/// </returns>
/// <remarks>
/// Returns the specified employee, if it exists and the current user has access to it. This can depend on any combination of user roles, cost centres, locations, organisation charts etc.
/// </remarks>
/// <response code="404">The specified employee does not exist, or the current user does not have access to it.</response>
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(Employee))]
[ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(ProblemDetails))]
[HttpGet("{id:long}")]
public async Task<IActionResult> GetById(long id)
{
var results = await _dbContext.Employees.FirstOrDefaultAsync(e => e.Id == id);
if (results == null)
{
return NotFound();
}
return Ok(results);
}
gets rendered in OpenAPI 3 as:
I still need to generate sample data to use in the responses, but it's looking very good, so thanks again @RicoSuter !
@RicoSuter The example from @davidkeaveny works perfectly. In my case, I forgot the documentation file. I guess, you can close this issue.
I believe it would still be beneficial to use ProducesResponseType attribute. 1 - it's supplied with ASP.NET 2 - it doesn't force me to specify the return type two times Also, in most cases I'm okay with just showing the default status code description and overriding it with a custom description is not desired.
Plus, neither XML comments nor SwaggerResponse work with web API conventions
/// <summary>
/// Returns the requested Contract with the given Id
/// </summary>
/// <remarks>*Requires Authorization</remarks>
/// <returns>A Contract</returns>
/// <response code="200">Request completed Successfully</response>
/// <response code="400">Bad Request</response>
/// <response code="401">Unathorized Request</response>
/// <response code="500">Interal Error has occured</response>
[HttpGet("{id}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(Exception), StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Exception), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(Exception), StatusCodes.Status500InternalServerError)]
So this is an example block of code that gets repeated around 100 times in our codebase.
I managed to move all the ProducesResponseType
to our custom convention and apply it to the whole codebase through 1 cmd.
However because the ProducesResponseType
doesnt contain any field for Description
we have to use the xml docs to provide the description. I am not sure why .NetCore doesnt include a description field.
Is anyone else with the same issue?
Yeah this is currently a limitation. You can implement a global custom operation processor (IOperationProcessor) which adds the descriptions to all operations with the convention.
Or use an xmlinclude (one line) and load the xml descs from a single xml file
Does the data gets initialized with default values ? Because that's what I get. Is there a way to show the values I set?
<example> { "Id": "1", "Name": "Name1" } </example>
On UI rather than giving me the values it shows 0 and string.
@davidkeaveny
So in @SeppPenner 's case, you've got all the above, apart from the
<remarks />
tag, so I'm guessing you don't have the<DocumentationFile />
property set in your.csproj
I was losing my mind trying to figure out why none of my XML summaries were showing up in the exported json file or in the web ui. The comment above here led me to the answer. My solution was to:
Add the following dependencies:
Add this line to the csproj
file.
<GenerateDocumentationFile>true</GenerateDocumentationFile>
For me, I got hung up on the fact that simply setting a DocumentationFile
won't cut it. It needs to be named correctly and in the proper place for it to be picked up.
(From https://github.com/RicoSuter/NJsonSchema/wiki/XML-Documentation#net-core )
A quick hack to add missing response status descriptions:
services.AddSwaggerDocument(config =>
{
config.PostProcess = document =>
document.Paths.Values
.SelectMany(p => p.Values)
.SelectMany(p => p.Responses)
.Where(r => string.IsNullOrWhiteSpace(r.Value.Description))
.ToList()
.ForEach(res => {
if (descriptions.ContainsKey(res.Key))
res.Value.Description = descriptions[res.Key];
});
...
var descriptions = new Dictionary<string, string>
{
{ "200", "OK" },
{ "201", "Created" },
{ "202", "Accepted" },
{ "400", "Bad Request" },
{ "401", "Unauthorized" },
{ "403", "Forbidden" },
{ "404", "Not Found" },
{ "405", "Mehtod Not Allowed" },
{ "406", "Not Acceptable" },
{ "500", "Server Error" },
};
I using this:
/// <param name="command">An instance of the CreatePatientCommand</param>
/// <returns>The status of the operation</returns>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>
/// <response code="200">If the item exist</response>
[HttpPost]
[Produces("application/json")]
[ProducesResponseType(typeof(string), StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status200OK)]
and a config in my.cspj
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
Update by @RicoSuter: Documentation about how to specify the response descriptions with XML Docs.
I'm on a .NET Core 2.1 Web API project and trying to obtain a complete swagger documentation like Swagger PetStore Demo. I've enabled the XML comments on my project, by adding the
<GenerateDocumentationFile>
tag on the.csproj
file:I'm using this syntax on my controllers:
I also tried with
SwaggerResponse
attribute:but without any result.
This is what I get:
This is what I want, like in PetStore Demo (red circle are my missing values):