diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Internal/ApiBehaviorApplicationModelProvider.cs b/src/Microsoft.AspNetCore.Mvc.Core/Internal/ApiBehaviorApplicationModelProvider.cs index bb44d1165e..4733d85c3c 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/Internal/ApiBehaviorApplicationModelProvider.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/Internal/ApiBehaviorApplicationModelProvider.cs @@ -57,6 +57,13 @@ namespace Microsoft.AspNetCore.Mvc.Internal foreach (var controllerModel in context.Result.Controllers) { var isApiController = controllerModel.Attributes.OfType().Any(); + if (isApiController && + controllerModel.ApiExplorer.IsVisible == null) + { + // Enable ApiExplorer for the controller if it wasn't already explicitly configured. + controllerModel.ApiExplorer.IsVisible = true; + } + var controllerHasSelectorModel = controllerModel.Selectors.Any(s => s.AttributeRouteModel != null); foreach (var actionModel in controllerModel.Actions) diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/ApiBehaviorApplicationModelProviderTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/ApiBehaviorApplicationModelProviderTest.cs index 5aa1ff119b..7f042b7b2d 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/ApiBehaviorApplicationModelProviderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/ApiBehaviorApplicationModelProviderTest.cs @@ -102,6 +102,47 @@ namespace Microsoft.AspNetCore.Mvc.Internal }); } + [Fact] + public void OnProvidersExecuting_MakesControllerVisibleInApiExplorer_IfItIsAnnotatedWithAttribute() + { + // Arrange + var context = GetContext(typeof(TestApiController)); + var options = new TestOptionsManager(new ApiBehaviorOptions + { + SuppressModelStateInvalidFilter = true, + }); + + var provider = GetProvider(options); + + // Act + provider.OnProvidersExecuting(context); + + // Assert + var controller = Assert.Single(context.Result.Controllers); + Assert.True(controller.ApiExplorer.IsVisible); + } + + [Fact] + public void OnProvidersExecuting_DoesNotModifyVisibilityInApiExplorer_IfValueIsAlreadySet() + { + // Arrange + var context = GetContext(typeof(TestApiController)); + context.Result.Controllers[0].ApiExplorer.IsVisible = false; + var options = new TestOptionsManager(new ApiBehaviorOptions + { + SuppressModelStateInvalidFilter = true, + }); + + var provider = GetProvider(options); + + // Act + provider.OnProvidersExecuting(context); + + // Assert + var controller = Assert.Single(context.Result.Controllers); + Assert.False(controller.ApiExplorer.IsVisible); + } + [Fact] public void OnProvidersExecuting_ThrowsIfControllerWithAttribute_HasActionsWithoutAttributeRouting() {