Skip to content

Commit c64f36d

Browse files
authored
Add default rules for setting operation ID (#55814)
1 parent 4a20983 commit c64f36d

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

src/OpenApi/src/Services/OpenApiDocumentService.cs

+6
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using Microsoft.AspNetCore.Mvc;
1313
using Microsoft.AspNetCore.Mvc.ApiExplorer;
1414
using Microsoft.AspNetCore.Mvc.ModelBinding;
15+
using Microsoft.AspNetCore.Routing;
1516
using Microsoft.AspNetCore.WebUtilities;
1617
using Microsoft.Extensions.DependencyInjection;
1718
using Microsoft.Extensions.Hosting;
@@ -140,6 +141,7 @@ private OpenApiOperation GetOperation(ApiDescription description, HashSet<OpenAp
140141
}
141142
var operation = new OpenApiOperation
142143
{
144+
OperationId = GetOperationId(description),
143145
Summary = GetSummary(description),
144146
Description = GetDescription(description),
145147
Responses = GetResponses(description),
@@ -156,6 +158,10 @@ private OpenApiOperation GetOperation(ApiDescription description, HashSet<OpenAp
156158
private static string? GetDescription(ApiDescription description)
157159
=> description.ActionDescriptor.EndpointMetadata.OfType<IEndpointDescriptionMetadata>().LastOrDefault()?.Description;
158160

161+
private static string? GetOperationId(ApiDescription description)
162+
=> description.ActionDescriptor.AttributeRouteInfo?.Name ??
163+
description.ActionDescriptor.EndpointMetadata.OfType<IEndpointNameMetadata>().LastOrDefault()?.EndpointName;
164+
159165
private static List<OpenApiTag>? GetTags(ApiDescription description)
160166
{
161167
var actionDescriptor = description.ActionDescriptor;

src/OpenApi/test/Services/OpenApiDocumentService/OpenApiDocumentServiceTests.Operations.cs

+56
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
using Microsoft.AspNetCore.Builder;
55
using Microsoft.AspNetCore.Http;
6+
using Microsoft.AspNetCore.Mvc;
7+
using Microsoft.AspNetCore.Routing;
68
using Microsoft.OpenApi.Models;
79

810
public partial class OpenApiDocumentServiceTests
@@ -178,4 +180,58 @@ await VerifyOpenApiDocument(builder, document =>
178180
});
179181
});
180182
}
183+
184+
[Fact]
185+
public async Task GetOpenApiOperation_CapturesEndpointNameAsOperationId()
186+
{
187+
// Arrange
188+
var builder = CreateBuilder();
189+
190+
// Act
191+
builder.MapGet("/api/todos", () => { }).WithName("GetTodos");
192+
193+
// Assert
194+
await VerifyOpenApiDocument(builder, document =>
195+
{
196+
var operation = document.Paths["/api/todos"].Operations[OperationType.Get];
197+
Assert.Equal("GetTodos", operation.OperationId);
198+
199+
});
200+
}
201+
202+
[Fact]
203+
public async Task GetOpenApiOperation_CapturesEndpointNameAttributeAsOperationId()
204+
{
205+
// Arrange
206+
var builder = CreateBuilder();
207+
208+
// Act
209+
builder.MapGet("/api/todos", [EndpointName("GetTodos")] () => { });
210+
211+
// Assert
212+
await VerifyOpenApiDocument(builder, document =>
213+
{
214+
var operation = document.Paths["/api/todos"].Operations[OperationType.Get];
215+
Assert.Equal("GetTodos", operation.OperationId);
216+
217+
});
218+
}
219+
220+
[Fact]
221+
public async Task GetOpenApiOperation_CapturesRouteAttributeAsOperationId()
222+
{
223+
// Act
224+
var action = CreateActionDescriptor(nameof(ActionWithRouteAttributeName));
225+
226+
// Assert
227+
await VerifyOpenApiDocument(action, document =>
228+
{
229+
var operation = document.Paths["/api/todos"].Operations[OperationType.Get];
230+
Assert.Equal("GetTodos", operation.OperationId);
231+
232+
});
233+
}
234+
235+
[Route("/api/todos", Name = "GetTodos")]
236+
private void ActionWithRouteAttributeName() { }
181237
}

src/OpenApi/test/Services/OpenApiDocumentServiceTestsBase.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,9 @@ public ControllerActionDescriptor CreateActionDescriptor(string methodName = nul
189189

190190
action.AttributeRouteInfo = new()
191191
{
192-
Template = action.MethodInfo.GetCustomAttribute<RouteAttribute>()?.Template
192+
Template = action.MethodInfo.GetCustomAttribute<RouteAttribute>()?.Template,
193+
Name = action.MethodInfo.GetCustomAttribute<RouteAttribute>()?.Name,
194+
Order = action.MethodInfo.GetCustomAttribute<RouteAttribute>()?.Order ?? 0,
193195
};
194196
action.RouteValues.Add("controller", "Test");
195197
action.RouteValues.Add("action", action.MethodInfo.Name);

0 commit comments

Comments
 (0)