зеркало из https://github.com/dotnet/aspnetcore.git
Support EndpointGroupName metadata in MVC ApiExplorer (#37264)
* Support EndpointGroupName metadata in MVC ApiExplorer * Address feedback from peer review * Update src/Mvc/Mvc.ApiExplorer/src/DefaultApiDescriptionProvider.cs Co-authored-by: Pranav K <prkrishn@hotmail.com> Co-authored-by: Pranav K <prkrishn@hotmail.com>
This commit is contained in:
Родитель
0cff8a75a3
Коммит
fa946a82e9
|
@ -71,13 +71,17 @@ namespace Microsoft.AspNetCore.Mvc.ApiExplorer
|
|||
continue;
|
||||
}
|
||||
|
||||
// ApiDescriptionActionData is only added to the ControllerActionDescriptor if
|
||||
// the action is marked as `IsVisible` to the ApiExplorer. This null-check is
|
||||
// effectively asserting if the endpoint should be generated into the final
|
||||
// OpenAPI metadata.
|
||||
var extensionData = action.GetProperty<ApiDescriptionActionData>();
|
||||
if (extensionData != null)
|
||||
{
|
||||
var httpMethods = GetHttpMethods(action);
|
||||
foreach (var httpMethod in httpMethods)
|
||||
{
|
||||
context.Results.Add(CreateApiDescription(action, httpMethod, extensionData.GroupName));
|
||||
context.Results.Add(CreateApiDescription(action, httpMethod, GetGroupName(action, extensionData)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -463,6 +467,19 @@ namespace Microsoft.AspNetCore.Mvc.ApiExplorer
|
|||
.ToArray();
|
||||
}
|
||||
|
||||
private static string? GetGroupName(ControllerActionDescriptor action, ApiDescriptionActionData extensionData)
|
||||
{
|
||||
// The `GroupName` set in the `ApiDescriptionActionData` is either the
|
||||
// group name set via [ApiExplorerSettings(GroupName = "foo")] on the
|
||||
// action or controller. So, this lookup favors the following sequence:
|
||||
// - EndpointGroupName on the action, if it is set
|
||||
// - EndpointGroupName on the controller, if it is set
|
||||
// - ApiExplorerSettings.GroupName on the action, if it is set
|
||||
// - ApiExplorerSettings.GroupName on the controller, if it is set
|
||||
var endpointGroupName = action.EndpointMetadata.OfType<IEndpointGroupNameMetadata>().LastOrDefault();
|
||||
return endpointGroupName?.EndpointGroupName ?? extensionData.GroupName;
|
||||
}
|
||||
|
||||
private class ApiParameterDescriptionContext
|
||||
{
|
||||
public ModelMetadata ModelMetadata { get; }
|
||||
|
|
|
@ -88,6 +88,37 @@ namespace Microsoft.AspNetCore.Mvc.Description
|
|||
Assert.Equal("Customers", description.GroupName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetApiDescription_PopulatesGroupName_FromMetadata()
|
||||
{
|
||||
// Arrange
|
||||
var action = CreateActionDescriptor();
|
||||
action.EndpointMetadata = new List<object>() { new EndpointGroupNameAttribute("Customers") };
|
||||
|
||||
// Act
|
||||
var descriptions = GetApiDescriptions(action);
|
||||
|
||||
// Assert
|
||||
var description = Assert.Single(descriptions);
|
||||
Assert.Equal("Customers", description.GroupName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetApiDescription_PopulatesGroupName_FromMetadataOrExtensionData()
|
||||
{
|
||||
// Arrange
|
||||
var action = CreateActionDescriptor();
|
||||
action.EndpointMetadata = new List<object>() { new EndpointGroupNameAttribute("Customers") };
|
||||
action.GetProperty<ApiDescriptionActionData>().GroupName = "NotUsedCustomers";
|
||||
|
||||
// Act
|
||||
var descriptions = GetApiDescriptions(action);
|
||||
|
||||
// Assert
|
||||
var description = Assert.Single(descriptions);
|
||||
Assert.Equal("Customers", description.GroupName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetApiDescription_HttpMethodIsNullWithoutConstraint()
|
||||
{
|
||||
|
|
|
@ -120,6 +120,34 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
Assert.Equal("SetOnAction", description.GroupName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiExplorer_GroupName_SetByEndpointMetadataOnController()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/ApiExplorerApiController/ActionWithIdParameter");
|
||||
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<List<ApiExplorerData>>(body);
|
||||
|
||||
// Assert
|
||||
var description = Assert.Single(result);
|
||||
Assert.Equal("GroupNameOnController", description.GroupName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiExplorer_GroupName_SetByEndpointMetadataOnAction()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/ApiExplorerApiController/ActionWithSomeParameters");
|
||||
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<List<ApiExplorerData>>(body);
|
||||
|
||||
// Assert
|
||||
var description = Assert.Single(result);
|
||||
Assert.Equal("GroupNameOnAction", description.GroupName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiExplorer_RouteTemplate_DisplaysFixedRoute()
|
||||
{
|
||||
|
|
|
@ -4,15 +4,18 @@
|
|||
using System.IO;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
|
||||
namespace ApiExplorerWebSite
|
||||
{
|
||||
[Route("ApiExplorerApiController/[action]")]
|
||||
[ApiController]
|
||||
[EndpointGroupName("GroupNameOnController")]
|
||||
public class ApiExplorerApiController : Controller
|
||||
{
|
||||
public IActionResult ActionWithoutParameters() => Ok();
|
||||
|
||||
[EndpointGroupName("GroupNameOnAction")]
|
||||
public void ActionWithSomeParameters(object input)
|
||||
{
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче