diff --git a/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/ActionModel.cs b/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/ActionModel.cs index 3d09bfd119..689c8ff9b3 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/ActionModel.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/ActionModel.cs @@ -13,6 +13,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels { ActionMethod = actionMethod; + ApiExplorer = new ApiExplorerModel(); Attributes = new List(); ActionConstraints = new List(); Filters = new List(); @@ -24,8 +25,6 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels { ActionMethod = other.ActionMethod; ActionName = other.ActionName; - ApiExplorerGroupName = other.ApiExplorerGroupName; - ApiExplorerIsVisible = other.ApiExplorerIsVisible; IsActionNameMatchRequired = other.IsActionNameMatchRequired; // Not making a deep copy of the controller, this action still belongs to the same controller. @@ -38,6 +37,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels HttpMethods = new List(other.HttpMethods); // Make a deep copy of other 'model' types. + ApiExplorer = new ApiExplorerModel(other.ApiExplorer); Parameters = new List(other.Parameters.Select(p => new ParameterModel(p))); if (other.AttributeRouteModel != null) @@ -51,6 +51,15 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels public string ActionName { get; set; } + /// + /// Gets or sets the for this action. + /// + /// + /// Setting the value of any properties on will override any + /// values set on the associated . + /// + public ApiExplorerModel ApiExplorer { get; set; } + public List Attributes { get; private set; } public ControllerModel Controller { get; set; } @@ -64,18 +73,5 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels public List Parameters { get; private set; } public AttributeRouteModel AttributeRouteModel { get; set; } - - /// - /// If true, objects will be created for this action. - /// If null then the value of will be used. - /// - public bool? ApiExplorerIsVisible { get; set; } - - /// - /// The value for of - /// objects created for actions defined by this controller. - /// If null then the value of will be used. - /// - public string ApiExplorerGroupName { get; set; } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/ApiExplorerModel.cs b/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/ApiExplorerModel.cs new file mode 100644 index 0000000000..800ebf587e --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/ApiExplorerModel.cs @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.Mvc.ApplicationModels +{ + /// + /// A model for ApiExplorer properties associated with a controller or action. + /// + public class ApiExplorerModel + { + /// + /// Creates a new . + /// + public ApiExplorerModel() + { + } + + /// + /// Creates a new with properties copied from . + /// + /// The to copy. + public ApiExplorerModel([NotNull] ApiExplorerModel other) + { + GroupName = other.GroupName; + IsVisible = other.IsVisible; + } + + /// + /// If true, objects will be created for the associated + /// controller or action. + /// + /// + /// Set this value to configure whether or not the associated controller or action will appear in ApiExplorer. + /// + public bool? IsVisible { get; set; } + + /// + /// The value for of + /// objects created for the associated controller or action. + /// + public string GroupName { get; set; } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/ControllerModel.cs b/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/ControllerModel.cs index 4aeb5aa493..347ca9ef48 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/ControllerModel.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/ControllerModel.cs @@ -14,6 +14,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels ControllerType = controllerType; Actions = new List(); + ApiExplorer = new ApiExplorerModel(); Attributes = new List(); AttributeRoutes = new List(); ActionConstraints = new List(); @@ -23,8 +24,6 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels public ControllerModel([NotNull] ControllerModel other) { - ApiExplorerGroupName = other.ApiExplorerGroupName; - ApiExplorerIsVisible = other.ApiExplorerIsVisible; ControllerName = other.ControllerName; ControllerType = other.ControllerType; @@ -39,6 +38,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels // Make a deep copy of other 'model' types. Actions = new List(other.Actions.Select(a => new ActionModel(a))); + ApiExplorer = new ApiExplorerModel(other.ApiExplorer); AttributeRoutes = new List( other.AttributeRoutes.Select(a => new AttributeRouteModel(a))); } @@ -47,8 +47,15 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels public List Actions { get; private set; } + /// + /// Gets or sets the for this controller. + /// + public ApiExplorerModel ApiExplorer { get; set; } + public ApplicationModel Application { get; set; } + public List AttributeRoutes { get; private set; } + public List Attributes { get; private set; } public string ControllerName { get; set; } @@ -58,19 +65,5 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels public List Filters { get; private set; } public List RouteConstraints { get; private set; } - - public List AttributeRoutes { get; private set; } - - /// - /// If true, objects will be created for actions defined by - /// this controller. - /// - public bool? ApiExplorerIsVisible { get; set; } - - /// - /// The value for of - /// objects created for actions defined by this controller. - /// - public string ApiExplorerGroupName { get; set; } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/DefaultActionModelBuilder.cs b/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/DefaultActionModelBuilder.cs index 73bd9d54db..2ce7d90a18 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/DefaultActionModelBuilder.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/DefaultActionModelBuilder.cs @@ -194,13 +194,13 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels var apiVisibility = attributes.OfType().FirstOrDefault(); if (apiVisibility != null) { - actionModel.ApiExplorerIsVisible = !apiVisibility.IgnoreApi; + actionModel.ApiExplorer.IsVisible = !apiVisibility.IgnoreApi; } var apiGroupName = attributes.OfType().FirstOrDefault(); if (apiGroupName != null) { - actionModel.ApiExplorerGroupName = apiGroupName.GroupName; + actionModel.ApiExplorer.GroupName = apiGroupName.GroupName; } var httpMethods = attributes.OfType(); diff --git a/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/DefaultControllerModelBuilder.cs b/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/DefaultControllerModelBuilder.cs index 24c478602a..464c05bc87 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/DefaultControllerModelBuilder.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/DefaultControllerModelBuilder.cs @@ -110,13 +110,13 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels var apiVisibility = attributes.OfType().FirstOrDefault(); if (apiVisibility != null) { - controllerModel.ApiExplorerIsVisible = !apiVisibility.IgnoreApi; + controllerModel.ApiExplorer.IsVisible = !apiVisibility.IgnoreApi; } var apiGroupName = attributes.OfType().FirstOrDefault(); if (apiGroupName != null) { - controllerModel.ApiExplorerGroupName = apiGroupName.GroupName; + controllerModel.ApiExplorer.GroupName = apiGroupName.GroupName; } return controllerModel; diff --git a/src/Microsoft.AspNet.Mvc.Core/ControllerActionDescriptorBuilder.cs b/src/Microsoft.AspNet.Mvc.Core/ControllerActionDescriptorBuilder.cs index a78a7be7e3..7ec79baad5 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ControllerActionDescriptorBuilder.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ControllerActionDescriptorBuilder.cs @@ -297,12 +297,12 @@ namespace Microsoft.AspNet.Mvc ActionModel action, ControllerModel controller) { - var apiExplorerIsVisible = action.ApiExplorerIsVisible ?? controller.ApiExplorerIsVisible ?? false; + var apiExplorerIsVisible = action.ApiExplorer?.IsVisible ?? controller.ApiExplorer?.IsVisible ?? false; if (apiExplorerIsVisible) { var apiExplorerActionData = new ApiDescriptionActionData() { - GroupName = action.ApiExplorerGroupName ?? controller.ApiExplorerGroupName, + GroupName = action.ApiExplorer?.GroupName ?? controller.ApiExplorer?.GroupName, }; actionDescriptor.SetProperty(apiExplorerActionData); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/ActionModelTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/ActionModelTest.cs index 2dcf250264..57f2ff5e18 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/ActionModelTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/ActionModelTest.cs @@ -23,11 +23,16 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels var route = new AttributeRouteModel(new HttpGetAttribute("api/Products")); action.AttributeRouteModel = route; + var apiExplorer = action.ApiExplorer; + apiExplorer.IsVisible = false; + apiExplorer.GroupName = "group1"; + // Act var action2 = new ActionModel(action); // Assert Assert.NotSame(action, action2.Parameters[0]); + Assert.NotSame(apiExplorer, action2.ApiExplorer); Assert.NotSame(route, action2.AttributeRouteModel); } @@ -39,8 +44,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels action.ActionConstraints.Add(new HttpMethodConstraint(new string[] { "GET" })); action.ActionName = "Edit"; - action.ApiExplorerGroupName = "group"; - action.ApiExplorerIsVisible = true; + action.Attributes.Add(new HttpGetAttribute()); action.Controller = new ControllerModel(typeof(TestController).GetTypeInfo()); action.Filters.Add(new AuthorizeAttribute()); @@ -53,7 +57,9 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels // Assert foreach (var property in typeof(ActionModel).GetProperties()) { - if (property.Name.Equals("Parameters") || property.Name.Equals("AttributeRouteModel")) + if (property.Name.Equals("ApiExplorer") || + property.Name.Equals("AttributeRouteModel") || + property.Name.Equals("Parameters")) { // This test excludes other ApplicationModel objects on purpose because we deep copy them. continue; diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/ControllerModelTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/ControllerModelTest.cs index ee7288a0a8..15603583ea 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/ControllerModelTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/ControllerModelTest.cs @@ -23,12 +23,17 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels var route = new AttributeRouteModel(new HttpGetAttribute("api/Products")); controller.AttributeRoutes.Add(route); + var apiExplorer = controller.ApiExplorer; + controller.ApiExplorer.GroupName = "group"; + controller.ApiExplorer.IsVisible = true; + // Act var controller2 = new ControllerModel(controller); // Assert Assert.NotSame(action, controller2.Actions[0]); Assert.NotSame(route, controller2.AttributeRoutes[0]); + Assert.NotSame(apiExplorer, controller2.ApiExplorer); Assert.NotSame(controller.ActionConstraints, controller2.ActionConstraints); Assert.NotSame(controller.Actions, controller2.Actions); @@ -44,8 +49,6 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels var controller = new ControllerModel(typeof(TestController).GetTypeInfo()); controller.ActionConstraints.Add(new HttpMethodConstraint(new string[] { "GET" })); - controller.ApiExplorerGroupName = "group"; - controller.ApiExplorerIsVisible = true; controller.Application = new ApplicationModel(); controller.Attributes.Add(new HttpGetAttribute()); controller.ControllerName = "cool"; @@ -58,7 +61,9 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels // Assert foreach (var property in typeof(ControllerModel).GetProperties()) { - if (property.Name.Equals("Actions") || property.Name.Equals("AttributeRoutes")) + if (property.Name.Equals("Actions") || + property.Name.Equals("AttributeRoutes") || + property.Name.Equals("ApiExplorer")) { // This test excludes other ApplicationModel objects on purpose because we deep copy them. continue; diff --git a/test/WebSites/ApiExplorerWebSite/ApiExplorerVisibilityDisabledConvention.cs b/test/WebSites/ApiExplorerWebSite/ApiExplorerVisibilityDisabledConvention.cs index 37f03975a7..2b1daf27b4 100644 --- a/test/WebSites/ApiExplorerWebSite/ApiExplorerVisibilityDisabledConvention.cs +++ b/test/WebSites/ApiExplorerWebSite/ApiExplorerVisibilityDisabledConvention.cs @@ -25,7 +25,7 @@ namespace ApiExplorer { if (controller.ControllerType == _type) { - controller.ApiExplorerIsVisible = false; + controller.ApiExplorer.IsVisible = false; } } } diff --git a/test/WebSites/ApiExplorerWebSite/ApiExplorerVisibilityEnabledConvention.cs b/test/WebSites/ApiExplorerWebSite/ApiExplorerVisibilityEnabledConvention.cs index 52064a9b80..664dd95d72 100644 --- a/test/WebSites/ApiExplorerWebSite/ApiExplorerVisibilityEnabledConvention.cs +++ b/test/WebSites/ApiExplorerWebSite/ApiExplorerVisibilityEnabledConvention.cs @@ -14,10 +14,10 @@ namespace ApiExplorer { foreach (var controller in application.Controllers) { - if (controller.ApiExplorerIsVisible == null) + if (controller.ApiExplorer.IsVisible == null) { - controller.ApiExplorerIsVisible = true; - controller.ApiExplorerGroupName = controller.ControllerName; + controller.ApiExplorer.IsVisible = true; + controller.ApiExplorer.GroupName = controller.ControllerName; } } }