Skip to content

Support mapping <returns> to response description #61920

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/OpenApi/gen/XmlCommentGenerator.Emitter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,13 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
}
}
}
// Applies `<returns>` on XML comments for operation with single response value.
if (methodComment.Returns is { } returns && operation.Responses is { Count: 1 })
{
var response = operation.Responses.First();
response.Value.Description = returns;
}
// Applies `<response>` on XML comments for operation with multiple response values.
if (methodComment.Responses is { Count: > 0} && operation.Responses is { Count: > 0 })
{
foreach (var response in operation.Responses)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public static class RouteHandlerExtensionMethods
/// <description>
/// A description of the action.
/// </description>
/// <returns>Returns the greeting.</returns>
public static string Get()
{
return "Hello, World!";
Expand All @@ -68,17 +69,20 @@ public static string Get2(string name)
}

/// <param name="name" example="Testy McTester">The name of the person.</param>
/// <returns>Returns the greeting.</returns>
/// <returns>Returns a different greeting.</returns>
public static string Get3(string name)
{
return $"Hello, {name}!";
}

/// <response code="404">Indicates that the value was not found.</response>
/// <returns>Indicates that the value was not found.</returns>
public static NotFound<string> Get4()
{
return TypedResults.NotFound("Not found!");
}

/// <returns>This gets ignored.</returns>
/// <response code="200">Indicates that the value is even.</response>
/// <response code="201">Indicates that the value is less than 50.</response>
/// <response code="404">Indicates that the value was not found.</response>
Expand Down Expand Up @@ -174,6 +178,7 @@ public static ValueTask<string> Get13()
/// <summary>
/// A summary of Get14.
/// </summary>
/// <returns>Returns the greeting.</returns>
public static async Task<Holder<string>> Get14()
{
await Task.Delay(1000);
Expand All @@ -182,6 +187,7 @@ public static async Task<Holder<string>> Get14()
/// <summary>
/// A summary of Get15.
/// </summary>
/// <response code="200">Returns the greeting.</response>
public static Task<Holder<string>> Get15()
{
return Task.FromResult(new Holder<string> { Value = "Hello, World!" });
Expand Down Expand Up @@ -234,6 +240,7 @@ await SnapshotTestHelper.VerifyOpenApi(compilation, document =>
var path = document.Paths["/1"].Operations[HttpMethod.Get];
Assert.Equal("A summary of the action.", path.Summary);
Assert.Equal("A description of the action.", path.Description);
Assert.Equal("Returns the greeting.", path.Responses["200"].Description);

var path2 = document.Paths["/2"].Operations[HttpMethod.Get];
Assert.Equal("The name of the person.", path2.Parameters[0].Description);
Expand All @@ -243,6 +250,7 @@ await SnapshotTestHelper.VerifyOpenApi(compilation, document =>
Assert.Equal("The name of the person.", path3.Parameters[0].Description);
var example = Assert.IsAssignableFrom<JsonNode>(path3.Parameters[0].Example);
Assert.Equal("\"Testy McTester\"", example.ToJsonString());
Assert.Equal("Returns the greeting.", path3.Responses["200"].Description);

var path4 = document.Paths["/4"].Operations[HttpMethod.Get];
var response = path4.Responses["404"];
Expand Down Expand Up @@ -285,9 +293,11 @@ await SnapshotTestHelper.VerifyOpenApi(compilation, document =>

var path14 = document.Paths["/14"].Operations[HttpMethod.Get];
Assert.Equal("A summary of Get14.", path14.Summary);
Assert.Equal("Returns the greeting.", path14.Responses["200"].Description);

var path15 = document.Paths["/15"].Operations[HttpMethod.Get];
Assert.Equal("A summary of Get15.", path15.Summary);
Assert.Equal("Returns the greeting.", path15.Responses["200"].Description);

var path16 = document.Paths["/16"].Operations[HttpMethod.Post];
Assert.Equal("A summary of Post16.", path16.Summary);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,13 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
}
}
}
// Applies `<returns>` on XML comments for operation with single response value.
if (methodComment.Returns is { } returns && operation.Responses is { Count: 1 })
{
var response = operation.Responses.First();
response.Value.Description = returns;
}
// Applies `<response>` on XML comments for operation with multiple response values.
if (methodComment.Responses is { Count: > 0} && operation.Responses is { Count: > 0 })
{
foreach (var response in operation.Responses)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,13 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
}
}
}
// Applies `<returns>` on XML comments for operation with single response value.
if (methodComment.Returns is { } returns && operation.Responses is { Count: 1 })
{
var response = operation.Responses.First();
response.Value.Description = returns;
}
// Applies `<response>` on XML comments for operation with multiple response values.
if (methodComment.Responses is { Count: > 0} && operation.Responses is { Count: > 0 })
{
foreach (var response in operation.Responses)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,13 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
}
}
}
// Applies `<returns>` on XML comments for operation with single response value.
if (methodComment.Returns is { } returns && operation.Responses is { Count: 1 })
{
var response = operation.Responses.First();
response.Value.Description = returns;
}
// Applies `<response>` on XML comments for operation with multiple response values.
if (methodComment.Responses is { Count: > 0} && operation.Responses is { Count: > 0 })
{
foreach (var response in operation.Responses)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,13 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
}
}
}
// Applies `<returns>` on XML comments for operation with single response value.
if (methodComment.Returns is { } returns && operation.Responses is { Count: 1 })
{
var response = operation.Responses.First();
response.Value.Description = returns;
}
// Applies `<response>` on XML comments for operation with multiple response values.
if (methodComment.Responses is { Count: > 0} && operation.Responses is { Count: > 0 })
{
foreach (var response in operation.Responses)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ private static Dictionary<string, XmlComment> GenerateCacheEntries()
{
var cache = new Dictionary<string, XmlComment>();

cache.Add(@"M:RouteHandlerExtensionMethods.Get~System.String", new XmlComment(@"A summary of the action.", @"A description of the action.", null, null, null, false, null, null, null));
cache.Add(@"M:RouteHandlerExtensionMethods.Get~System.String", new XmlComment(@"A summary of the action.", @"A description of the action.", null, @"Returns the greeting.", null, false, null, null, null));
cache.Add(@"M:RouteHandlerExtensionMethods.Get2(System.String)~System.String", new XmlComment(null, null, null, null, null, false, null, [new XmlParameterComment(@"name", @"The name of the person.", null, false)], [new XmlResponseComment(@"200", @"Returns the greeting.", @"")]));
cache.Add(@"M:RouteHandlerExtensionMethods.Get3(System.String)~System.String", new XmlComment(null, null, null, null, null, false, null, [new XmlParameterComment(@"name", @"The name of the person.", @"Testy McTester", false)], null));
cache.Add(@"M:RouteHandlerExtensionMethods.Get4~Microsoft.AspNetCore.Http.HttpResults.NotFound{System.String}", new XmlComment(null, null, null, null, null, false, null, null, [new XmlResponseComment(@"404", @"Indicates that the value was not found.", @"")]));
cache.Add(@"M:RouteHandlerExtensionMethods.Get5~Microsoft.AspNetCore.Http.HttpResults.Results{Microsoft.AspNetCore.Http.HttpResults.NotFound{System.String},Microsoft.AspNetCore.Http.HttpResults.Ok{System.String},Microsoft.AspNetCore.Http.HttpResults.Created}", new XmlComment(null, null, null, null, null, false, null, null, [new XmlResponseComment(@"200", @"Indicates that the value is even.", @""), new XmlResponseComment(@"201", @"Indicates that the value is less than 50.", @""), new XmlResponseComment(@"404", @"Indicates that the value was not found.", @"")]));
cache.Add(@"M:RouteHandlerExtensionMethods.Get3(System.String)~System.String", new XmlComment(null, null, null, @"Returns the greeting.", null, false, null, [new XmlParameterComment(@"name", @"The name of the person.", @"Testy McTester", false)], null));
cache.Add(@"M:RouteHandlerExtensionMethods.Get4~Microsoft.AspNetCore.Http.HttpResults.NotFound{System.String}", new XmlComment(null, null, null, @"Indicates that the value was not found.", null, false, null, null, null));
cache.Add(@"M:RouteHandlerExtensionMethods.Get5~Microsoft.AspNetCore.Http.HttpResults.Results{Microsoft.AspNetCore.Http.HttpResults.NotFound{System.String},Microsoft.AspNetCore.Http.HttpResults.Ok{System.String},Microsoft.AspNetCore.Http.HttpResults.Created}", new XmlComment(null, null, null, @"This gets ignored.", null, false, null, null, [new XmlResponseComment(@"200", @"Indicates that the value is even.", @""), new XmlResponseComment(@"201", @"Indicates that the value is less than 50.", @""), new XmlResponseComment(@"404", @"Indicates that the value was not found.", @"")]));
cache.Add(@"M:RouteHandlerExtensionMethods.Post6(User)~Microsoft.AspNetCore.Http.IResult", new XmlComment(@"Creates a new user.", null, @"Sample request:
POST /6
{
Expand All @@ -91,8 +91,8 @@ private static Dictionary<string, XmlComment> GenerateCacheEntries()
cache.Add(@"M:RouteHandlerExtensionMethods.Get11~System.Threading.Tasks.ValueTask", new XmlComment(@"A summary of Get11.", null, null, null, null, false, null, null, null));
cache.Add(@"M:RouteHandlerExtensionMethods.Get12~System.Threading.Tasks.Task{System.String}", new XmlComment(@"A summary of Get12.", null, null, null, null, false, null, null, null));
cache.Add(@"M:RouteHandlerExtensionMethods.Get13~System.Threading.Tasks.ValueTask{System.String}", new XmlComment(@"A summary of Get13.", null, null, null, null, false, null, null, null));
cache.Add(@"M:RouteHandlerExtensionMethods.Get14~System.Threading.Tasks.Task{Holder{System.String}}", new XmlComment(@"A summary of Get14.", null, null, null, null, false, null, null, null));
cache.Add(@"M:RouteHandlerExtensionMethods.Get15~System.Threading.Tasks.Task{Holder{System.String}}", new XmlComment(@"A summary of Get15.", null, null, null, null, false, null, null, null));
cache.Add(@"M:RouteHandlerExtensionMethods.Get14~System.Threading.Tasks.Task{Holder{System.String}}", new XmlComment(@"A summary of Get14.", null, null, @"Returns the greeting.", null, false, null, null, null));
cache.Add(@"M:RouteHandlerExtensionMethods.Get15~System.Threading.Tasks.Task{Holder{System.String}}", new XmlComment(@"A summary of Get15.", null, null, null, null, false, null, null, [new XmlResponseComment(@"200", @"Returns the greeting.", @"")]));
cache.Add(@"M:RouteHandlerExtensionMethods.Post16(Example)", new XmlComment(@"A summary of Post16.", null, null, null, null, false, null, null, null));
cache.Add(@"M:RouteHandlerExtensionMethods.Get17(System.Int32[])~System.Int32[][]", new XmlComment(@"A summary of Get17.", null, null, null, null, false, null, null, null));

Expand Down Expand Up @@ -376,6 +376,13 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
}
}
}
// Applies `<returns>` on XML comments for operation with single response value.
if (methodComment.Returns is { } returns && operation.Responses is { Count: 1 })
{
var response = operation.Responses.First();
response.Value.Description = returns;
}
// Applies `<response>` on XML comments for operation with multiple response values.
if (methodComment.Responses is { Count: > 0} && operation.Responses is { Count: > 0 })
{
foreach (var response in operation.Responses)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,13 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
}
}
}
// Applies `<returns>` on XML comments for operation with single response value.
if (methodComment.Returns is { } returns && operation.Responses is { Count: 1 })
{
var response = operation.Responses.First();
response.Value.Description = returns;
}
// Applies `<response>` on XML comments for operation with multiple response values.
if (methodComment.Responses is { Count: > 0} && operation.Responses is { Count: > 0 })
{
foreach (var response in operation.Responses)
Expand Down
Loading