diff --git a/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/ApplicationModelProviderContext.cs b/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/ApplicationModelProviderContext.cs
new file mode 100644
index 0000000000..e6bb3fa760
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/ApplicationModelProviderContext.cs
@@ -0,0 +1,27 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Reflection;
+using Microsoft.Framework.Internal;
+
+namespace Microsoft.AspNet.Mvc.ApplicationModels
+{
+ ///
+ /// A context object for .
+ ///
+ public class ApplicationModelProviderContext
+ {
+ public ApplicationModelProviderContext([NotNull] IEnumerable controllerTypes)
+ {
+ ControllerTypes = controllerTypes;
+ }
+
+ public IEnumerable ControllerTypes { get; }
+
+ ///
+ /// Gets the .
+ ///
+ public ApplicationModel Result { get; } = new ApplicationModel();
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/DefaultActionModelBuilder.cs b/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/DefaultApplicationModelProvider.cs
similarity index 58%
rename from src/Microsoft.AspNet.Mvc.Core/ApplicationModels/DefaultActionModelBuilder.cs
rename to src/Microsoft.AspNet.Mvc.Core/ApplicationModels/DefaultApplicationModelProvider.cs
index b9c653eaea..81bd32780f 100644
--- a/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/DefaultActionModelBuilder.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/DefaultApplicationModelProvider.cs
@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
@@ -6,31 +6,262 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.AspNet.Authorization;
-using Microsoft.AspNet.Cors;
using Microsoft.AspNet.Cors.Core;
using Microsoft.AspNet.Mvc.ApiExplorer;
+using Microsoft.AspNet.Mvc.Filters;
using Microsoft.AspNet.Mvc.ModelBinding;
-using Microsoft.AspNet.Mvc.ModelBinding.Metadata;
using Microsoft.AspNet.Mvc.Routing;
using Microsoft.Framework.Internal;
using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Mvc.ApplicationModels
{
- ///
- /// A default implementation of .
- ///
- public class DefaultActionModelBuilder : IActionModelBuilder
+ public class DefaultApplicationModelProvider : IApplicationModelProvider
{
private readonly AuthorizationOptions _authorizationOptions;
+ private readonly ICollection _globalFilters;
- public DefaultActionModelBuilder(IOptions authorizationOptions)
+ public DefaultApplicationModelProvider(
+ IOptions mvcOptionsAccessor,
+ IOptions authorizationOptionsAccessor)
{
- _authorizationOptions = authorizationOptions?.Options ?? new AuthorizationOptions();
+ _globalFilters = mvcOptionsAccessor.Options.Filters;
+ _authorizationOptions = authorizationOptionsAccessor.Options;
}
///
- public IEnumerable BuildActionModels([NotNull] TypeInfo typeInfo, [NotNull] MethodInfo methodInfo)
+ public int Order
+ {
+ get
+ {
+ return DefaultOrder.DefaultFrameworkSortOrder;
+ }
+ }
+
+ ///
+ public virtual void OnProvidersExecuting([NotNull] ApplicationModelProviderContext context)
+ {
+ foreach (var filter in _globalFilters)
+ {
+ context.Result.Filters.Add(filter);
+ }
+
+ foreach (var controllerType in context.ControllerTypes)
+ {
+ var controllerModels = BuildControllerModels(controllerType);
+ if (controllerModels != null)
+ {
+ foreach (var controllerModel in controllerModels)
+ {
+ context.Result.Controllers.Add(controllerModel);
+ controllerModel.Application = context.Result;
+
+ foreach (var propertyHelper in PropertyHelper.GetProperties(controllerType.AsType()))
+ {
+ var propertyInfo = propertyHelper.Property;
+ var propertyModel = CreatePropertyModel(propertyInfo);
+ if (propertyModel != null)
+ {
+ propertyModel.Controller = controllerModel;
+ controllerModel.ControllerProperties.Add(propertyModel);
+ }
+ }
+
+ foreach (var methodInfo in controllerType.AsType().GetMethods())
+ {
+ var actionModels = BuildActionModels(controllerType, methodInfo);
+ if (actionModels != null)
+ {
+ foreach (var actionModel in actionModels)
+ {
+ actionModel.Controller = controllerModel;
+ controllerModel.Actions.Add(actionModel);
+
+ foreach (var parameterInfo in actionModel.ActionMethod.GetParameters())
+ {
+ var parameterModel = CreateParameterModel(parameterInfo);
+ if (parameterModel != null)
+ {
+ parameterModel.Action = actionModel;
+ actionModel.Parameters.Add(parameterModel);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ public virtual void OnProvidersExecuted([NotNull] ApplicationModelProviderContext context)
+ {
+ // Intentionally empty.
+ }
+
+ ///
+ /// Creates the instances for the given controller .
+ ///
+ /// The controller .
+ ///
+ /// A set of instances for the given controller or
+ /// null if the does not represent a controller.
+ ///
+ protected virtual IEnumerable BuildControllerModels([NotNull] TypeInfo typeInfo)
+ {
+ var controllerModel = CreateControllerModel(typeInfo);
+ yield return controllerModel;
+ }
+
+ ///
+ /// Creates a for the given .
+ ///
+ /// The .
+ /// A for the given .
+ protected virtual ControllerModel CreateControllerModel([NotNull] TypeInfo typeInfo)
+ {
+ // For attribute routes on a controller, we want want to support 'overriding' routes on a derived
+ // class. So we need to walk up the hierarchy looking for the first class to define routes.
+ //
+ // Then we want to 'filter' the set of attributes, so that only the effective routes apply.
+ var currentTypeInfo = typeInfo;
+ var objectTypeInfo = typeof(object).GetTypeInfo();
+
+ IRouteTemplateProvider[] routeAttributes = null;
+
+ do
+ {
+ routeAttributes = currentTypeInfo
+ .GetCustomAttributes(inherit: false)
+ .OfType()
+ .ToArray();
+
+ if (routeAttributes.Length > 0)
+ {
+ // Found 1 or more route attributes.
+ break;
+ }
+
+ currentTypeInfo = currentTypeInfo.BaseType.GetTypeInfo();
+ }
+ while (currentTypeInfo != objectTypeInfo);
+
+ // CoreCLR returns IEnumerable from GetCustomAttributes - the OfType
+ // is needed to so that the result of ToArray() is object
+ var attributes = typeInfo.GetCustomAttributes(inherit: true).OfType().ToArray();
+
+ // This is fairly complicated so that we maintain referential equality between items in
+ // ControllerModel.Attributes and ControllerModel.Attributes[*].Attribute.
+ var filteredAttributes = new List();
+ foreach (var attribute in attributes)
+ {
+ if (attribute is IRouteTemplateProvider)
+ {
+ // This attribute is a route-attribute, leave it out.
+ }
+ else
+ {
+ filteredAttributes.Add(attribute);
+ }
+ }
+ filteredAttributes.AddRange(routeAttributes);
+
+ attributes = filteredAttributes.ToArray();
+
+ var controllerModel = new ControllerModel(typeInfo, attributes);
+ AddRange(
+ controllerModel.AttributeRoutes, routeAttributes.Select(a => new AttributeRouteModel(a)));
+
+ controllerModel.ControllerName =
+ typeInfo.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) ?
+ typeInfo.Name.Substring(0, typeInfo.Name.Length - "Controller".Length) :
+ typeInfo.Name;
+
+ AddRange(controllerModel.ActionConstraints, attributes.OfType());
+ AddRange(controllerModel.Filters, attributes.OfType());
+ AddRange(controllerModel.RouteConstraints, attributes.OfType());
+
+ var enableCors = attributes.OfType().SingleOrDefault();
+ if (enableCors != null)
+ {
+ controllerModel.Filters.Add(new CorsAuthorizationFilterFactory(enableCors.PolicyName));
+ }
+
+ var disableCors = attributes.OfType().SingleOrDefault();
+ if (disableCors != null)
+ {
+ controllerModel.Filters.Add(new DisableCorsAuthorizationFilter());
+ }
+
+ var policy = AuthorizationPolicy.Combine(_authorizationOptions, attributes.OfType());
+ if (policy != null)
+ {
+ controllerModel.Filters.Add(new AuthorizeFilter(policy));
+ }
+
+ var apiVisibility = attributes.OfType().FirstOrDefault();
+ if (apiVisibility != null)
+ {
+ controllerModel.ApiExplorer.IsVisible = !apiVisibility.IgnoreApi;
+ }
+
+ var apiGroupName = attributes.OfType().FirstOrDefault();
+ if (apiGroupName != null)
+ {
+ controllerModel.ApiExplorer.GroupName = apiGroupName.GroupName;
+ }
+
+ // Controllers can implement action filter and result filter interfaces. We add
+ // a special delegating filter implementation to the pipeline to handle it.
+ //
+ // This is needed because filters are instantiated before the controller.
+ if (typeof(IAsyncActionFilter).GetTypeInfo().IsAssignableFrom(typeInfo) ||
+ typeof(IActionFilter).GetTypeInfo().IsAssignableFrom(typeInfo))
+ {
+ controllerModel.Filters.Add(new ControllerActionFilter());
+ }
+ if (typeof(IAsyncResultFilter).GetTypeInfo().IsAssignableFrom(typeInfo) ||
+ typeof(IResultFilter).GetTypeInfo().IsAssignableFrom(typeInfo))
+ {
+ controllerModel.Filters.Add(new ControllerResultFilter());
+ }
+
+ return controllerModel;
+ }
+
+ ///
+ /// Creates a for the given .
+ ///
+ /// The .
+ /// A for the given .
+ protected virtual PropertyModel CreatePropertyModel([NotNull] PropertyInfo propertyInfo)
+ {
+ // CoreCLR returns IEnumerable from GetCustomAttributes - the OfType
+ // is needed to so that the result of ToArray() is object
+ var attributes = propertyInfo.GetCustomAttributes(inherit: true).OfType().ToArray();
+ var propertyModel = new PropertyModel(propertyInfo, attributes);
+ var bindingInfo = BindingInfo.GetBindingInfo(attributes);
+
+ propertyModel.BindingInfo = bindingInfo;
+ propertyModel.PropertyName = propertyInfo.Name;
+
+ return propertyModel;
+ }
+
+
+ ///
+ /// Creates the instances for the given action .
+ ///
+ /// The controller .
+ /// The action .
+ ///
+ /// A set of instances for the given action or
+ /// null if the does not represent an action.
+ ///
+ protected virtual IEnumerable BuildActionModels(
+ [NotNull] TypeInfo typeInfo,
+ [NotNull] MethodInfo methodInfo)
{
if (!IsAction(typeInfo, methodInfo))
{
@@ -214,19 +445,6 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
}
}
- foreach (var actionModel in actionModels)
- {
- foreach (var parameterInfo in actionModel.ActionMethod.GetParameters())
- {
- var parameterModel = CreateParameterModel(parameterInfo);
- if (parameterModel != null)
- {
- parameterModel.Action = actionModel;
- actionModel.Parameters.Add(parameterModel);
- }
- }
- }
-
return actionModels;
}
@@ -285,15 +503,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
return false;
}
- return
- methodInfo.IsPublic;
- }
-
- private bool IsIDisposableMethod(MethodInfo methodInfo, TypeInfo typeInfo)
- {
- return
- (typeof(IDisposable).GetTypeInfo().IsAssignableFrom(typeInfo) &&
- typeInfo.GetRuntimeInterfaceMap(typeof(IDisposable)).TargetMethods[0] == methodInfo);
+ return methodInfo.IsPublic;
}
///
@@ -402,6 +612,13 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
return parameterModel;
}
+ private bool IsIDisposableMethod(MethodInfo methodInfo, TypeInfo typeInfo)
+ {
+ return
+ (typeof(IDisposable).GetTypeInfo().IsAssignableFrom(typeInfo) &&
+ typeInfo.GetRuntimeInterfaceMap(typeof(IDisposable)).TargetMethods[0] == methodInfo);
+ }
+
private bool IsSilentRouteAttribute(IRouteTemplateProvider routeTemplateProvider)
{
return
diff --git a/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/DefaultControllerModelBuilder.cs b/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/DefaultControllerModelBuilder.cs
deleted file mode 100644
index 7a73d0d5c8..0000000000
--- a/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/DefaultControllerModelBuilder.cs
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using Microsoft.AspNet.Mvc.ApiExplorer;
-using Microsoft.AspNet.Authorization;
-using Microsoft.AspNet.Cors.Core;
-using Microsoft.AspNet.Mvc.Filters;
-using Microsoft.AspNet.Mvc.ModelBinding;
-using Microsoft.AspNet.Mvc.Routing;
-using Microsoft.Framework.Internal;
-using Microsoft.Framework.OptionsModel;
-
-namespace Microsoft.AspNet.Mvc.ApplicationModels
-{
- ///
- /// A default implementation of .
- ///
- public class DefaultControllerModelBuilder : IControllerModelBuilder
- {
- private readonly IActionModelBuilder _actionModelBuilder;
- private readonly AuthorizationOptions _authorizationOptions;
-
- ///
- /// Creates a new .
- ///
- /// The used to create actions.
- public DefaultControllerModelBuilder(
- IActionModelBuilder actionModelBuilder,
- IOptions authorizationOptions)
- {
- _actionModelBuilder = actionModelBuilder;
- _authorizationOptions = authorizationOptions?.Options ?? new AuthorizationOptions();
- }
-
- ///
- public ControllerModel BuildControllerModel([NotNull] TypeInfo typeInfo)
- {
- var controllerModel = CreateControllerModel(typeInfo);
- var controllerType = typeInfo.AsType();
-
- foreach (var methodInfo in controllerType.GetMethods())
- {
- var actionModels = _actionModelBuilder.BuildActionModels(typeInfo, methodInfo);
- if (actionModels != null)
- {
- foreach (var actionModel in actionModels)
- {
- actionModel.Controller = controllerModel;
- controllerModel.Actions.Add(actionModel);
- }
- }
- }
-
- foreach (var propertyHelper in PropertyHelper.GetProperties(controllerType))
- {
- var propertyInfo = propertyHelper.Property;
- var propertyModel = CreatePropertyModel(propertyInfo);
- if (propertyModel != null)
- {
- propertyModel.Controller = controllerModel;
- controllerModel.ControllerProperties.Add(propertyModel);
- }
- }
-
- return controllerModel;
- }
-
- ///
- /// Creates an for the given .
- ///
- /// The .
- /// A for the given .
- protected virtual ControllerModel CreateControllerModel([NotNull] TypeInfo typeInfo)
- {
- // For attribute routes on a controller, we want want to support 'overriding' routes on a derived
- // class. So we need to walk up the hierarchy looking for the first class to define routes.
- //
- // Then we want to 'filter' the set of attributes, so that only the effective routes apply.
- var currentTypeInfo = typeInfo;
- var objectTypeInfo = typeof(object).GetTypeInfo();
-
- IRouteTemplateProvider[] routeAttributes = null;
-
- do
- {
- routeAttributes = currentTypeInfo
- .GetCustomAttributes(inherit: false)
- .OfType()
- .ToArray();
-
- if (routeAttributes.Length > 0)
- {
- // Found 1 or more route attributes.
- break;
- }
-
- currentTypeInfo = currentTypeInfo.BaseType.GetTypeInfo();
- }
- while (currentTypeInfo != objectTypeInfo);
-
- // CoreCLR returns IEnumerable from GetCustomAttributes - the OfType
- // is needed to so that the result of ToArray() is object
- var attributes = typeInfo.GetCustomAttributes(inherit: true).OfType().ToArray();
-
- // This is fairly complicated so that we maintain referential equality between items in
- // ControllerModel.Attributes and ControllerModel.Attributes[*].Attribute.
- var filteredAttributes = new List();
- foreach (var attribute in attributes)
- {
- if (attribute is IRouteTemplateProvider)
- {
- // This attribute is a route-attribute, leave it out.
- }
- else
- {
- filteredAttributes.Add(attribute);
- }
- }
- filteredAttributes.AddRange(routeAttributes);
-
- attributes = filteredAttributes.ToArray();
-
- var controllerModel = new ControllerModel(typeInfo, attributes);
- AddRange(
- controllerModel.AttributeRoutes, routeAttributes.Select(a => new AttributeRouteModel(a)));
-
- controllerModel.ControllerName =
- typeInfo.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) ?
- typeInfo.Name.Substring(0, typeInfo.Name.Length - "Controller".Length) :
- typeInfo.Name;
-
- AddRange(controllerModel.ActionConstraints, attributes.OfType());
- AddRange(controllerModel.Filters, attributes.OfType());
- AddRange(controllerModel.RouteConstraints, attributes.OfType());
-
- var enableCors = attributes.OfType().SingleOrDefault();
- if (enableCors != null)
- {
- controllerModel.Filters.Add(new CorsAuthorizationFilterFactory(enableCors.PolicyName));
- }
-
- var disableCors = attributes.OfType().SingleOrDefault();
- if (disableCors != null)
- {
- controllerModel.Filters.Add(new DisableCorsAuthorizationFilter());
- }
-
- var policy = AuthorizationPolicy.Combine(_authorizationOptions, attributes.OfType());
- if (policy != null)
- {
- controllerModel.Filters.Add(new AuthorizeFilter(policy));
- }
-
- var apiVisibility = attributes.OfType().FirstOrDefault();
- if (apiVisibility != null)
- {
- controllerModel.ApiExplorer.IsVisible = !apiVisibility.IgnoreApi;
- }
-
- var apiGroupName = attributes.OfType().FirstOrDefault();
- if (apiGroupName != null)
- {
- controllerModel.ApiExplorer.GroupName = apiGroupName.GroupName;
- }
-
- // Controllers can implement action filter and result filter interfaces. We add
- // a special delegating filter implementation to the pipeline to handle it.
- //
- // This is needed because filters are instantiated before the controller.
- if (typeof(IAsyncActionFilter).GetTypeInfo().IsAssignableFrom(typeInfo) ||
- typeof(IActionFilter).GetTypeInfo().IsAssignableFrom(typeInfo))
- {
- controllerModel.Filters.Add(new ControllerActionFilter());
- }
- if (typeof(IAsyncResultFilter).GetTypeInfo().IsAssignableFrom(typeInfo) ||
- typeof(IResultFilter).GetTypeInfo().IsAssignableFrom(typeInfo))
- {
- controllerModel.Filters.Add(new ControllerResultFilter());
- }
-
- return controllerModel;
- }
-
- ///
- /// Creates a for the given .
- ///
- /// The .
- /// A for the given .
- protected virtual PropertyModel CreatePropertyModel([NotNull] PropertyInfo propertyInfo)
- {
- // CoreCLR returns IEnumerable from GetCustomAttributes - the OfType
- // is needed to so that the result of ToArray() is object
- var attributes = propertyInfo.GetCustomAttributes(inherit: true).OfType().ToArray();
- var propertyModel = new PropertyModel(propertyInfo, attributes);
- var bindingInfo = BindingInfo.GetBindingInfo(attributes);
-
- propertyModel.BindingInfo = bindingInfo;
- propertyModel.PropertyName = propertyInfo.Name;
-
- return propertyModel;
- }
-
- private static void AddRange(IList list, IEnumerable items)
- {
- foreach (var item in items)
- {
- list.Add(item);
- }
- }
- }
-}
diff --git a/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/IActionModelBuilder.cs b/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/IActionModelBuilder.cs
deleted file mode 100644
index f9737b0e77..0000000000
--- a/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/IActionModelBuilder.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Collections.Generic;
-using System.Reflection;
-using Microsoft.Framework.Internal;
-
-namespace Microsoft.AspNet.Mvc.ApplicationModels
-{
- ///
- /// Creates a set of for a method.
- ///
- public interface IActionModelBuilder
- {
- ///
- /// Creates a set of for a method. May return null or empty if
- /// is not an action method.
- ///
- /// The .
- /// The .
- /// A set of or null.
- ///
- /// Instances of returned from this interface should have their
- /// initialized.
- ///
- IEnumerable BuildActionModels([NotNull] TypeInfo typeInfo, [NotNull] MethodInfo methodInfo);
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/IApplicationModelProvider.cs b/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/IApplicationModelProvider.cs
new file mode 100644
index 0000000000..bd7d7a2201
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/IApplicationModelProvider.cs
@@ -0,0 +1,46 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.Framework.Internal;
+
+namespace Microsoft.AspNet.Mvc.ApplicationModels
+{
+ ///
+ /// Builds or modifies an for action discovery.
+ ///
+ public interface IApplicationModelProvider
+ {
+ ///
+ /// Gets the order value for determining the order of execution of providers. Providers execute in
+ /// ascending numeric value of the property.
+ ///
+ ///
+ ///
+ /// Providers are executed in an ordering determined by an ascending sort of the property.
+ /// A provider with a lower numeric value of will have its
+ /// called before that of a provider with a higher numeric value of
+ /// . The method is called in the reverse ordering after
+ /// all calls to . A provider with a lower numeric value of
+ /// will have its method called after that of a provider
+ /// with a higher numeric value of .
+ ///
+ ///
+ /// If two providers have the same numeric value of , then their relative execution order
+ /// is undefined.
+ ///
+ ///
+ int Order { get; }
+
+ ///
+ /// Executed for the first pass of building. See .
+ ///
+ /// The .
+ void OnProvidersExecuting([NotNull] ApplicationModelProviderContext context);
+
+ ///
+ /// Executed for the second pass of building. See .
+ ///
+ /// The .
+ void OnProvidersExecuted([NotNull] ApplicationModelProviderContext context);
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/IControllerModelBuilder.cs b/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/IControllerModelBuilder.cs
deleted file mode 100644
index 201f30a8bd..0000000000
--- a/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/IControllerModelBuilder.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Reflection;
-using Microsoft.Framework.Internal;
-
-namespace Microsoft.AspNet.Mvc.ApplicationModels
-{
- ///
- /// Creates a set of for a type.
- ///
- public interface IControllerModelBuilder
- {
- ///
- /// Creates a set of for a type. May return null or empty if
- /// is not a controller type.
- ///
- /// The .
- /// A or null.
- ///
- /// Instances of returned from this interface should have their
- /// initialized.
- ///
- ControllerModel BuildControllerModel([NotNull] TypeInfo typeInfo);
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Core/ControllerActionDescriptorProvider.cs b/src/Microsoft.AspNet.Mvc.Core/ControllerActionDescriptorProvider.cs
index 789b224c2e..29aacd2bf2 100644
--- a/src/Microsoft.AspNet.Mvc.Core/ControllerActionDescriptorProvider.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/ControllerActionDescriptorProvider.cs
@@ -2,8 +2,8 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
+using System.Linq;
using Microsoft.AspNet.Mvc.ApplicationModels;
-using Microsoft.AspNet.Mvc.Filters;
using Microsoft.Framework.Internal;
using Microsoft.Framework.OptionsModel;
@@ -11,19 +11,17 @@ namespace Microsoft.AspNet.Mvc.Core
{
public class ControllerActionDescriptorProvider : IActionDescriptorProvider
{
- private readonly IControllerModelBuilder _applicationModelBuilder;
+ private readonly IApplicationModelProvider[] _applicationModelProviders;
private readonly IControllerTypeProvider _controllerTypeProvider;
- private readonly IReadOnlyList _globalFilters;
private readonly IEnumerable _conventions;
- public ControllerActionDescriptorProvider([NotNull] IControllerTypeProvider controllerTypeProvider,
- [NotNull] IControllerModelBuilder applicationModelBuilder,
- [NotNull] IGlobalFilterProvider globalFilters,
- [NotNull] IOptions optionsAccessor)
+ public ControllerActionDescriptorProvider(
+ [NotNull] IControllerTypeProvider controllerTypeProvider,
+ [NotNull] IEnumerable applicationModelProviders,
+ [NotNull] IOptions optionsAccessor)
{
_controllerTypeProvider = controllerTypeProvider;
- _applicationModelBuilder = applicationModelBuilder;
- _globalFilters = globalFilters.Filters;
+ _applicationModelProviders = applicationModelProviders.OrderBy(p => p.Order).ToArray();
_conventions = optionsAccessor.Options.Conventions;
}
@@ -55,23 +53,20 @@ namespace Microsoft.AspNet.Mvc.Core
internal protected ApplicationModel BuildModel()
{
- var applicationModel = new ApplicationModel();
- foreach (var filter in _globalFilters)
+ var controllerTypes = _controllerTypeProvider.ControllerTypes;
+ var context = new ApplicationModelProviderContext(controllerTypes);
+
+ for (var i = 0; i < _applicationModelProviders.Length; i++)
{
- applicationModel.Filters.Add(filter);
+ _applicationModelProviders[i].OnProvidersExecuting(context);
}
- foreach (var type in _controllerTypeProvider.ControllerTypes)
+ for (var i = _applicationModelProviders.Length - 1 ; i >= 0; i--)
{
- var controllerModel = _applicationModelBuilder.BuildControllerModel(type);
- if (controllerModel != null)
- {
- controllerModel.Application = applicationModel;
- applicationModel.Controllers.Add(controllerModel);
- }
+ _applicationModelProviders[i].OnProvidersExecuted(context);
}
- return applicationModel;
+ return context.Result;
}
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Core/Filters/DefaultGlobalFilterProvider.cs b/src/Microsoft.AspNet.Mvc.Core/Filters/DefaultGlobalFilterProvider.cs
deleted file mode 100644
index 29aca07640..0000000000
--- a/src/Microsoft.AspNet.Mvc.Core/Filters/DefaultGlobalFilterProvider.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Collections.Generic;
-using System.Linq;
-using Microsoft.Framework.OptionsModel;
-
-namespace Microsoft.AspNet.Mvc.Filters
-{
- ///
- /// An implementation of based on .
- ///
- public class DefaultGlobalFilterProvider : IGlobalFilterProvider
- {
- private readonly IReadOnlyList _filters;
-
- ///
- /// Creates a new instance of .
- ///
- /// The options accessor for .
- public DefaultGlobalFilterProvider(IOptions optionsAccessor)
- {
- var filters = optionsAccessor.Options.Filters;
- _filters = filters.ToList();
- }
-
- ///
- public IReadOnlyList Filters
- {
- get
- {
- return _filters;
- }
- }
- }
-}
diff --git a/src/Microsoft.AspNet.Mvc.Core/Filters/IGlobalFilterProvider.cs b/src/Microsoft.AspNet.Mvc.Core/Filters/IGlobalFilterProvider.cs
deleted file mode 100644
index 2ceb34b729..0000000000
--- a/src/Microsoft.AspNet.Mvc.Core/Filters/IGlobalFilterProvider.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Collections.Generic;
-
-namespace Microsoft.AspNet.Mvc.Filters
-{
- ///
- /// Provides access to the collection of for globally registered filters.
- ///
- public interface IGlobalFilterProvider
- {
- ///
- /// Gets the collection of .
- ///
- IReadOnlyList Filters { get; }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc/MvcServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Mvc/MvcServiceCollectionExtensions.cs
index edcf53cb40..1d1a60b254 100644
--- a/src/Microsoft.AspNet.Mvc/MvcServiceCollectionExtensions.cs
+++ b/src/Microsoft.AspNet.Mvc/MvcServiceCollectionExtensions.cs
@@ -116,10 +116,8 @@ namespace Microsoft.Framework.DependencyInjection
// Core action discovery, filters and action execution.
- // These are consumed only when creating action descriptors, then they can be de-allocated
- services.TryAdd(ServiceDescriptor.Transient());
- services.TryAdd(ServiceDescriptor.Transient());
- services.TryAdd(ServiceDescriptor.Transient());
+ // This are consumed only when creating action descriptors, then they can be de-allocated
+ services.TryAdd(ServiceDescriptor.Transient());;
// This has a cache, so it needs to be a singleton
services.TryAdd(ServiceDescriptor.Singleton());
@@ -155,12 +153,12 @@ namespace Microsoft.Framework.DependencyInjection
services.TryAdd(ServiceDescriptor
.Singleton());
- // The IGlobalFilterProvider is used to build the action descriptors (likely once) and so should
- // remain transient to avoid keeping it in memory.
- services.TryAdd(ServiceDescriptor.Transient());
// multiple registration service
services.AddTransient();
+ // multiple registration service
+ services.AddTransient();
+
services.TryAdd(ServiceDescriptor.Transient());
services.TryAdd(ServiceDescriptor.Transient());
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/DefaultActionModelBuilderTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/DefaultApplicationModelProviderTest.cs
similarity index 68%
rename from test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/DefaultActionModelBuilderTest.cs
rename to test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/DefaultApplicationModelProviderTest.cs
index cb39b06884..b77f215a9e 100644
--- a/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/DefaultActionModelBuilderTest.cs
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/DefaultApplicationModelProviderTest.cs
@@ -1,21 +1,190 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
+using System.Threading.Tasks;
using Microsoft.AspNet.Authorization;
using Microsoft.AspNet.Cors.Core;
+using Microsoft.AspNet.Mvc.Filters;
+using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.Framework.Internal;
using Microsoft.Framework.OptionsModel;
-using Moq;
using Xunit;
namespace Microsoft.AspNet.Mvc.ApplicationModels
{
- public class DefaultActionModelBuilderTest
+ public class DefaultApplicationModelProviderTest
{
+ [Fact]
+ public void CreateControllerModel_DerivedFromControllerClass_HasFilter()
+ {
+ // Arrange
+ var builder = new TestApplicationModelProvider();
+ var typeInfo = typeof(StoreController).GetTypeInfo();
+
+ // Act
+ var model = builder.CreateControllerModel(typeInfo);
+
+ // Assert
+ var filter = Assert.Single(model.Filters);
+ Assert.IsType(filter);
+ }
+
+ [Fact]
+ public void CreateControllerModel_AuthorizeAttributeAddsAuthorizeFilter()
+ {
+ // Arrange
+ var builder = new TestApplicationModelProvider();
+ var typeInfo = typeof(AccountController).GetTypeInfo();
+
+ // Act
+ var model = builder.CreateControllerModel(typeInfo);
+
+ // Assert
+ Assert.True(model.Filters.Any(f => f is AuthorizeFilter));
+ }
+
+ [Fact]
+ public void CreateControllerModel_EnableCorsAttributeAddsCorsAuthorizationFilterFactory()
+ {
+ // Arrange
+ var builder = new TestApplicationModelProvider();
+ var typeInfo = typeof(CorsController).GetTypeInfo();
+
+ // Act
+ var model = builder.CreateControllerModel(typeInfo);
+
+ // Assert
+ Assert.Single(model.Filters, f => f is CorsAuthorizationFilterFactory);
+ }
+
+ [Fact]
+ public void OnProvidersExecuting_AddsControllerProperties()
+ {
+ // Arrange
+ var builder = new TestApplicationModelProvider();
+ var typeInfo = typeof(ModelBinderController).GetTypeInfo();
+
+ var context = new ApplicationModelProviderContext(new[] { typeInfo });
+
+ // Act
+ builder.OnProvidersExecuting(context);
+
+ // Assert
+ var model = Assert.Single(context.Result.Controllers);
+ Assert.Equal(2, model.ControllerProperties.Count);
+ Assert.Equal("Bound", model.ControllerProperties[0].PropertyName);
+ Assert.Equal(BindingSource.Query, model.ControllerProperties[0].BindingInfo.BindingSource);
+ Assert.NotNull(model.ControllerProperties[0].Controller);
+ var attribute = Assert.Single(model.ControllerProperties[0].Attributes);
+ Assert.IsType(attribute);
+ }
+
+ [Fact]
+ public void CreateControllerModel_DisableCorsAttributeAddsDisableCorsAuthorizationFilter()
+ {
+ // Arrange
+ var builder = new TestApplicationModelProvider();
+ var typeInfo = typeof(DisableCorsController).GetTypeInfo();
+
+ // Act
+ var model = builder.CreateControllerModel(typeInfo);
+
+ // Assert
+ Assert.True(model.Filters.Any(f => f is DisableCorsAuthorizationFilter));
+ }
+
+ // This class has a filter attribute, but doesn't implement any filter interfaces,
+ // so ControllerFilter is not present.
+ [Fact]
+ public void CreateControllerModel_ClassWithoutFilterInterfaces_HasNoControllerFilter()
+ {
+ // Arrange
+ var builder = new TestApplicationModelProvider();
+ var typeInfo = typeof(NoFiltersController).GetTypeInfo();
+
+ // Act
+ var model = builder.CreateControllerModel(typeInfo);
+
+ // Assert
+ var filter = Assert.Single(model.Filters);
+ Assert.IsType(filter);
+ }
+
+ [Fact]
+ public void CreateControllerModel_ClassWithFilterInterfaces_HasFilter()
+ {
+ // Arrange
+ var builder = new TestApplicationModelProvider();
+ var typeInfo = typeof(SomeFiltersController).GetTypeInfo();
+
+ // Act
+ var model = builder.CreateControllerModel(typeInfo);
+
+ // Assert
+ Assert.Single(model.Filters, f => f is ControllerActionFilter);
+ Assert.Single(model.Filters, f => f is ControllerResultFilter);
+ }
+
+ [Fact]
+ public void CreateControllerModel_ClassWithFilterInterfaces_UnsupportedType()
+ {
+ // Arrange
+ var builder = new TestApplicationModelProvider();
+ var typeInfo = typeof(UnsupportedFiltersController).GetTypeInfo();
+
+ // Act
+ var model = builder.CreateControllerModel(typeInfo);
+
+ // Assert
+ Assert.Empty(model.Filters);
+ }
+
+ [Fact]
+ public void CreateControllerModel_ClassWithInheritedRoutes()
+ {
+ // Arrange
+ var builder = new TestApplicationModelProvider();
+ var typeInfo = typeof(DerivedClassInheritingRoutesController).GetTypeInfo();
+
+ // Act
+ var model = builder.CreateControllerModel(typeInfo);
+
+ // Assert
+ Assert.Equal(2, model.AttributeRoutes.Count);
+ Assert.Equal(2, model.Attributes.Count);
+
+ var route = Assert.Single(model.AttributeRoutes, r => r.Template == "A");
+ Assert.Contains(route.Attribute, model.Attributes);
+
+ route = Assert.Single(model.AttributeRoutes, r => r.Template == "B");
+ Assert.Contains(route.Attribute, model.Attributes);
+ }
+
+ [Fact]
+ public void CreateControllerModel_ClassWithHiddenInheritedRoutes()
+ {
+ // Arrange
+ var builder = new TestApplicationModelProvider();
+ var typeInfo = typeof(DerivedClassHidingRoutesController).GetTypeInfo();
+
+ // Act
+ var model = builder.CreateControllerModel(typeInfo);
+
+ // Assert
+ Assert.Equal(2, model.AttributeRoutes.Count);
+ Assert.Equal(2, model.Attributes.Count);
+
+ var route = Assert.Single(model.AttributeRoutes, r => r.Template == "C");
+ Assert.Contains(route.Attribute, model.Attributes);
+
+ route = Assert.Single(model.AttributeRoutes, r => r.Template == "D");
+ Assert.Contains(route.Attribute, model.Attributes);
+ }
+
[Theory]
[InlineData("GetFromDerived", true)]
[InlineData("NewMethod", true)] // "NewMethod" is a public method declared with keyword "new".
@@ -23,7 +192,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
public void IsAction_WithInheritedMethods(string methodName, bool expected)
{
// Arrange
- var builder = CreateTestAccessibleActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var method = typeof(DerivedController).GetMethod(methodName);
Assert.NotNull(method);
@@ -38,7 +207,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
public void IsAction_OverridenMethodControllerClass()
{
// Arrange
- var builder = CreateTestAccessibleActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var method = typeof(BaseController).GetMethod(nameof(BaseController.Redirect));
Assert.NotNull(method);
@@ -53,7 +222,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
public void IsAction_PrivateMethod_FromUserDefinedController()
{
// Arrange
- var builder = CreateTestAccessibleActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var method = typeof(DerivedController).GetMethod(
"PrivateMethod",
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
@@ -70,7 +239,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
public void IsAction_OperatorOverloadingMethod_FromOperatorOverloadingController()
{
// Arrange
- var builder = CreateTestAccessibleActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var method = typeof(OperatorOverloadingController).GetMethod("op_Addition");
Assert.NotNull(method);
Assert.True(method.IsSpecialName);
@@ -86,7 +255,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
public void IsAction_GenericMethod_FromUserDefinedController()
{
// Arrange
- var builder = CreateTestAccessibleActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var method = typeof(DerivedController).GetMethod("GenericMethod");
Assert.NotNull(method);
@@ -101,7 +270,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
public void IsAction_OverridenNonActionMethod()
{
// Arrange
- var builder = CreateTestAccessibleActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var method = typeof(DerivedController).GetMethod("OverridenNonActionMethod");
Assert.NotNull(method);
@@ -120,7 +289,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
public void IsAction_OverriddenMethodsFromObjectClass(string methodName)
{
// Arrange
- var builder = CreateTestAccessibleActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var method = typeof(DerivedController).GetMethod(
methodName,
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
@@ -137,7 +306,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
public void IsAction_DerivedControllerIDisposableDisposeMethod()
{
// Arrange
- var builder = CreateTestAccessibleActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(DerivedController).GetTypeInfo();
var methodInfo =
typeInfo.GetRuntimeInterfaceMap(typeof(IDisposable)).TargetMethods[0];
@@ -155,7 +324,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
public void IsAction_DerivedControllerDisposeMethod()
{
// Arrange
- var builder = CreateTestAccessibleActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(DerivedController).GetTypeInfo();
var methodInfo =
typeInfo.GetRuntimeInterfaceMap(typeof(IDisposable)).TargetMethods[0];
@@ -177,7 +346,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
public void IsAction_OverriddenDisposeMethod()
{
// Arrange
- var builder = CreateTestAccessibleActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(DerivedOverriddenDisposeController).GetTypeInfo();
var method = typeInfo.GetDeclaredMethods("Dispose").SingleOrDefault();
Assert.NotNull(method);
@@ -193,7 +362,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
public void IsAction_NewDisposeMethod()
{
// Arrange
- var builder = CreateTestAccessibleActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(DerivedNewDisposeController).GetTypeInfo();
var method = typeInfo.GetDeclaredMethods("Dispose").SingleOrDefault();
Assert.NotNull(method);
@@ -209,7 +378,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
public void IsAction_PocoControllerIDisposableDisposeMethod()
{
// Arrange
- var builder = CreateTestAccessibleActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(IDisposablePocoController).GetTypeInfo();
var methodInfo =
typeInfo.GetRuntimeInterfaceMap(typeof(IDisposable)).TargetMethods[0];
@@ -227,7 +396,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
public void IsAction_PocoControllerDisposeMethod()
{
// Arrange
- var builder = CreateTestAccessibleActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(IDisposablePocoController).GetTypeInfo();
var methodInfo =
typeInfo.GetRuntimeInterfaceMap(typeof(IDisposable)).TargetMethods[0];
@@ -249,7 +418,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
public void IsAction_SimplePocoControllerDisposeMethod()
{
// Arrange
- var builder = CreateTestAccessibleActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(SimplePocoController).GetTypeInfo();
var methods = typeInfo.GetMethods().Where(m => m.Name.Equals("Dispose"));
@@ -272,7 +441,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
public void IsAction_StaticMethods(string methodName)
{
// Arrange
- var builder = CreateTestAccessibleActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var method = typeof(DerivedController).GetMethod(
methodName,
BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
@@ -289,7 +458,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
public void BuildActionModel_EnableCorsAttributeAddsCorsAuthorizationFilterFactory()
{
// Arrange
- var builder = new DefaultActionModelBuilder(authorizationOptions: null);
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(EnableCorsController).GetTypeInfo();
var method = typeInfo.GetMethod("Action");
@@ -305,8 +474,8 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
public void BuildActionModel_DisableCorsAttributeAddsDisableCorsAuthorizationFilter()
{
// Arrange
- var builder = new DefaultActionModelBuilder(authorizationOptions: null);
- var typeInfo = typeof(DisableCorsController).GetTypeInfo();
+ var builder = new TestApplicationModelProvider();
+ var typeInfo = typeof(DisableCorsActionController).GetTypeInfo();
var method = typeInfo.GetMethod("Action");
// Act
@@ -318,10 +487,10 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
}
[Fact]
- public void GetActions_ConventionallyRoutedAction_WithoutHttpConstraints()
+ public void BuildActionModels_ConventionallyRoutedAction_WithoutHttpConstraints()
{
// Arrange
- var builder = CreateTestDefaultActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(ConventionallyRoutedController).GetTypeInfo();
var actionName = nameof(ConventionallyRoutedController.Edit);
@@ -337,10 +506,10 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
}
[Fact]
- public void GetActions_ConventionallyRoutedAction_WithHttpConstraints()
+ public void BuildActionModels_ConventionallyRoutedAction_WithHttpConstraints()
{
// Arrange
- var builder = CreateTestDefaultActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(ConventionallyRoutedController).GetTypeInfo();
var actionName = nameof(ConventionallyRoutedController.Update);
@@ -358,13 +527,13 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
}
[Fact]
- public void GetActions_BaseAuthorizeFiltersAreStillValidWhenOverriden()
+ public void BuildActionModels_BaseAuthorizeFiltersAreStillValidWhenOverriden()
{
// Arrange
- var options = new AuthorizationOptions();
- options.AddPolicy("Base", policy => policy.RequireClaim("Basic").RequireClaim("Basic2"));
- options.AddPolicy("Derived", policy => policy.RequireClaim("Derived"));
- var builder = CreateTestDefaultActionModelBuilder(options);
+ var builder = new TestApplicationModelProvider();
+ builder.AuthorizationOptions.AddPolicy("Base", policy => policy.RequireClaim("Basic").RequireClaim("Basic2"));
+ builder.AuthorizationOptions.AddPolicy("Derived", policy => policy.RequireClaim("Derived"));
+
var typeInfo = typeof(DerivedController).GetTypeInfo();
var actionName = nameof(DerivedController.Authorize);
@@ -381,10 +550,10 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
}
[Fact]
- public void GetActions_ConventionallyRoutedActionWithHttpConstraints_AndInvalidRouteTemplateProvider()
+ public void BuildActionModels_ConventionallyRoutedActionWithHttpConstraints_AndInvalidRouteTemplateProvider()
{
// Arrange
- var builder = CreateTestDefaultActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(ConventionallyRoutedController).GetTypeInfo();
var actionName = nameof(ConventionallyRoutedController.Delete);
@@ -403,10 +572,10 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
}
[Fact]
- public void GetActions_ConventionallyRoutedAction_WithMultipleHttpConstraints()
+ public void BuildActionModels_ConventionallyRoutedAction_WithMultipleHttpConstraints()
{
// Arrange
- var builder = CreateTestDefaultActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(ConventionallyRoutedController).GetTypeInfo();
var actionName = nameof(ConventionallyRoutedController.Details);
@@ -422,10 +591,10 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
}
[Fact]
- public void GetActions_ConventionallyRoutedAction_WithMultipleOverlappingHttpConstraints()
+ public void BuildActionModels_ConventionallyRoutedAction_WithMultipleOverlappingHttpConstraints()
{
// Arrange
- var builder = CreateTestDefaultActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(ConventionallyRoutedController).GetTypeInfo();
var actionName = nameof(ConventionallyRoutedController.List);
@@ -442,10 +611,10 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
}
[Fact]
- public void GetActions_AttributeRouteOnAction()
+ public void BuildActionModels_AttributeRouteOnAction()
{
// Arrange
- var builder = CreateTestDefaultActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(NoRouteAttributeOnControllerController).GetTypeInfo();
var actionName = nameof(NoRouteAttributeOnControllerController.Edit);
@@ -467,10 +636,10 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
}
[Fact]
- public void GetActions_AttributeRouteOnAction_RouteAttribute()
+ public void BuildActionModels_AttributeRouteOnAction_RouteAttribute()
{
// Arrange
- var builder = CreateTestDefaultActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(NoRouteAttributeOnControllerController).GetTypeInfo();
var actionName = nameof(NoRouteAttributeOnControllerController.Update);
@@ -491,10 +660,10 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
}
[Fact]
- public void GetActions_AttributeRouteOnAction_AcceptVerbsAttributeWithTemplate()
+ public void BuildActionModels_AttributeRouteOnAction_AcceptVerbsAttributeWithTemplate()
{
// Arrange
- var builder = CreateTestDefaultActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(NoRouteAttributeOnControllerController).GetTypeInfo();
var actionName = nameof(NoRouteAttributeOnControllerController.List);
@@ -515,10 +684,10 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
}
[Fact]
- public void GetActions_AttributeRouteOnAction_CreatesOneActionInforPerRouteTemplate()
+ public void BuildActionModels_AttributeRouteOnAction_CreatesOneActionInforPerRouteTemplate()
{
// Arrange
- var builder = CreateTestDefaultActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(NoRouteAttributeOnControllerController).GetTypeInfo();
var actionName = nameof(NoRouteAttributeOnControllerController.Index);
@@ -546,10 +715,10 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
}
[Fact]
- public void GetActions_NoRouteOnController_AllowsConventionallyRoutedActions_OnTheSameController()
+ public void BuildActionModels_NoRouteOnController_AllowsConventionallyRoutedActions_OnTheSameController()
{
// Arrange
- var builder = CreateTestDefaultActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(NoRouteAttributeOnControllerController).GetTypeInfo();
var actionName = nameof(NoRouteAttributeOnControllerController.Remove);
@@ -571,10 +740,10 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
[Theory]
[InlineData(typeof(SingleRouteAttributeController))]
[InlineData(typeof(MultipleRouteAttributeController))]
- public void GetActions_RouteAttributeOnController_CreatesAttributeRoute_ForNonAttributedActions(Type controller)
+ public void BuildActionModels_RouteAttributeOnController_CreatesAttributeRoute_ForNonAttributedActions(Type controller)
{
// Arrange
- var builder = CreateTestDefaultActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = controller.GetTypeInfo();
// Act
@@ -595,10 +764,10 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
[Theory]
[InlineData(typeof(SingleRouteAttributeController))]
[InlineData(typeof(MultipleRouteAttributeController))]
- public void GetActions_RouteOnController_CreatesOneActionInforPerRouteTemplateOnAction(Type controller)
+ public void BuildActionModels_RouteOnController_CreatesOneActionInforPerRouteTemplateOnAction(Type controller)
{
// Arrange
- var builder = CreateTestDefaultActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = controller.GetTypeInfo();
// Act
@@ -624,10 +793,10 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
}
[Fact]
- public void GetActions_MixedHttpVerbsAndRoutes_EmptyVerbWithRoute()
+ public void BuildActionModels_MixedHttpVerbsAndRoutes_EmptyVerbWithRoute()
{
// Arrange
- var builder = CreateTestDefaultActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(MixedHttpVerbsAndRouteAttributeController).GetTypeInfo();
var actionName = nameof(MixedHttpVerbsAndRouteAttributeController.VerbAndRoute);
@@ -641,10 +810,10 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
}
[Fact]
- public void GetActions_MixedHttpVerbsAndRoutes_MultipleEmptyVerbsWithMultipleRoutes()
+ public void BuildActionModels_MixedHttpVerbsAndRoutes_MultipleEmptyVerbsWithMultipleRoutes()
{
// Arrange
- var builder = CreateTestDefaultActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(MixedHttpVerbsAndRouteAttributeController).GetTypeInfo();
var actionName = nameof(MixedHttpVerbsAndRouteAttributeController.MultipleVerbsAndRoutes);
@@ -662,10 +831,10 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
}
[Fact]
- public void GetActions_MixedHttpVerbsAndRoutes_MultipleEmptyAndNonEmptyVerbsWithMultipleRoutes()
+ public void BuildActionModels_MixedHttpVerbsAndRoutes_MultipleEmptyAndNonEmptyVerbsWithMultipleRoutes()
{
// Arrange
- var builder = CreateTestDefaultActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(MixedHttpVerbsAndRouteAttributeController).GetTypeInfo();
var actionName = nameof(MixedHttpVerbsAndRouteAttributeController.MultipleVerbsWithAnyWithoutTemplateAndRoutes);
@@ -686,10 +855,10 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
}
[Fact]
- public void GetActions_MixedHttpVerbsAndRoutes_MultipleEmptyAndNonEmptyVerbs()
+ public void BuildActionModels_MixedHttpVerbsAndRoutes_MultipleEmptyAndNonEmptyVerbs()
{
// Arrange
- var builder = CreateTestDefaultActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(MixedHttpVerbsAndRouteAttributeController).GetTypeInfo();
var actionName = nameof(MixedHttpVerbsAndRouteAttributeController.Invalid);
@@ -707,10 +876,10 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
}
[Fact]
- public void GetActions_InheritedAttributeRoutes()
+ public void BuildActionModels_InheritedAttributeRoutes()
{
// Arrange
- var builder = CreateTestDefaultActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(DerivedClassInheritsAttributeRoutesController).GetTypeInfo();
var actionName = nameof(DerivedClassInheritsAttributeRoutesController.Edit);
@@ -730,10 +899,10 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
}
[Fact]
- public void GetActions_InheritedAttributeRoutesOverridden()
+ public void BuildActionModels_InheritedAttributeRoutesOverridden()
{
// Arrange
- var builder = CreateTestDefaultActionModelBuilder();
+ var builder = new TestApplicationModelProvider();
var typeInfo = typeof(DerivedClassOverridesAttributeRoutesController).GetTypeInfo();
var actionName = nameof(DerivedClassOverridesAttributeRoutesController.Edit);
@@ -752,31 +921,6 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
Assert.Contains(action.AttributeRouteModel.Attribute, action.Attributes);
}
- private static DefaultActionModelBuilder CreateTestDefaultActionModelBuilder(
- AuthorizationOptions authOptions = null)
- {
- var options = new Mock>();
- options.Setup(o => o.Options).Returns(authOptions ?? new AuthorizationOptions());
- return new DefaultActionModelBuilder(options.Object);
- }
-
- private static AccessibleActionModelBuilder CreateTestAccessibleActionModelBuilder()
- {
- var options = new Mock>();
- options.Setup(o => o.Options).Returns(new AuthorizationOptions());
- return new AccessibleActionModelBuilder(options.Object);
- }
-
- private class AccessibleActionModelBuilder : DefaultActionModelBuilder
- {
- public AccessibleActionModelBuilder(IOptions options) : base(options) { }
-
- public new bool IsAction([NotNull] TypeInfo typeInfo, [NotNull]MethodInfo methodInfo)
- {
- return base.IsAction(typeInfo, methodInfo);
- }
- }
-
private class BaseClassWithAttributeRoutesController
{
[Route("A")]
@@ -1039,7 +1183,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
}
}
- private class DisableCorsController
+ private class DisableCorsActionController
{
[DisableCors]
public void Action()
@@ -1087,5 +1231,147 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
}
}
}
+
+ [Route("A")]
+ [Route("B")]
+ private class BaseClassWithRoutesController
+ {
+ }
+
+ private class DerivedClassInheritingRoutesController : BaseClassWithRoutesController
+ {
+ }
+
+ [Route("C")]
+ [Route("D")]
+ private class DerivedClassHidingRoutesController : BaseClassWithRoutesController
+ {
+ }
+
+ private class StoreController : Mvc.Controller
+ {
+ }
+
+ [Produces("application/json")]
+ public class NoFiltersController
+ {
+ }
+
+ [Authorize]
+ public class AccountController
+ {
+ }
+
+ [EnableCors("policy")]
+ public class CorsController
+ {
+ }
+
+ [DisableCors]
+ public class DisableCorsController
+ {
+ }
+
+ public class ModelBinderController
+ {
+ [FromQuery]
+ public string Bound { get; set; }
+
+ public string Unbound { get; set; }
+ }
+
+ public class SomeFiltersController : IAsyncActionFilter, IResultFilter
+ {
+ public Task OnActionExecutionAsync(
+ [NotNull] ActionExecutingContext context,
+ [NotNull] ActionExecutionDelegate next)
+ {
+ return null;
+ }
+
+ public void OnResultExecuted([NotNull] ResultExecutedContext context)
+ {
+ }
+
+ public void OnResultExecuting([NotNull]ResultExecutingContext context)
+ {
+ }
+ }
+
+ private class UnsupportedFiltersController : IExceptionFilter, IAuthorizationFilter, IAsyncResourceFilter
+ {
+ public void OnAuthorization([NotNull]AuthorizationContext context)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void OnException([NotNull]ExceptionContext context)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task OnResourceExecutionAsync([NotNull]ResourceExecutingContext context, [NotNull]ResourceExecutionDelegate next)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ private class TestApplicationModelProvider : DefaultApplicationModelProvider
+ {
+ public TestApplicationModelProvider()
+ : this(
+ new MockMvcOptionsAccessor(),
+ new OptionsManager(Enumerable.Empty>()))
+ {
+ }
+
+ public TestApplicationModelProvider(
+ IOptions options,
+ IOptions authorizationOptions)
+ : base(options, authorizationOptions)
+ {
+ Options = options.Options;
+ AuthorizationOptions = authorizationOptions.Options;
+ }
+
+ public AuthorizationOptions AuthorizationOptions { get; }
+
+ public MvcOptions Options { get; }
+
+ public new IEnumerable BuildControllerModels(TypeInfo typeInfo)
+ {
+ return base.BuildControllerModels(typeInfo);
+ }
+
+ public new ControllerModel CreateControllerModel(TypeInfo typeInfo)
+ {
+ return base.CreateControllerModel(typeInfo);
+ }
+
+ public new PropertyModel CreatePropertyModel(PropertyInfo propertyInfo)
+ {
+ return base.CreatePropertyModel(propertyInfo);
+ }
+
+ public new IEnumerable BuildActionModels(TypeInfo typeInfo, MethodInfo methodInfo)
+ {
+ return base.BuildActionModels(typeInfo, methodInfo);
+ }
+
+ public new ActionModel CreateActionModel(MethodInfo methodInfo, IReadOnlyList attributes)
+ {
+ return base.CreateActionModel(methodInfo, attributes);
+ }
+
+ public new bool IsAction(TypeInfo typeInfo, MethodInfo methodInfo)
+ {
+ return base.IsAction(typeInfo, methodInfo);
+ }
+
+ public new ParameterModel CreateParameterModel(ParameterInfo parameterInfo)
+ {
+ return base.CreateParameterModel(parameterInfo);
+ }
+ }
}
}
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/DefaultControllerModelBuilderTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/DefaultControllerModelBuilderTest.cs
deleted file mode 100644
index 4166aba409..0000000000
--- a/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/DefaultControllerModelBuilderTest.cs
+++ /dev/null
@@ -1,281 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Linq;
-using System.Reflection;
-using System.Threading.Tasks;
-using Microsoft.AspNet.Authorization;
-using Microsoft.AspNet.Cors.Core;
-using Microsoft.AspNet.Mvc.Filters;
-using Microsoft.AspNet.Mvc.ModelBinding;
-using Microsoft.Framework.Internal;
-using Microsoft.Framework.OptionsModel;
-using Moq;
-using Xunit;
-
-namespace Microsoft.AspNet.Mvc.ApplicationModels
-{
- public class DefaultControllerModelBuilderTest
- {
- [Fact]
- public void BuildControllerModel_DerivedFromControllerClass_HasFilter()
- {
- // Arrange
- var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null), null);
- var typeInfo = typeof(StoreController).GetTypeInfo();
-
- // Act
- var model = builder.BuildControllerModel(typeInfo);
-
- // Assert
- var filter = Assert.Single(model.Filters);
- Assert.IsType(filter);
- }
-
- [Fact]
- public void BuildControllerModel_AuthorizeAttributeAddsAuthorizeFilter()
- {
- // Arrange
- var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null), null);
- var typeInfo = typeof(AccountController).GetTypeInfo();
-
- // Act
- var model = builder.BuildControllerModel(typeInfo);
-
- // Assert
- Assert.True(model.Filters.Any(f => f is AuthorizeFilter));
- }
-
- [Fact]
- public void BuildControllerModel_EnableCorsAttributeAddsCorsAuthorizationFilterFactory()
- {
- // Arrange
- var corsOptions = new CorsOptions();
- corsOptions.AddPolicy("policy", new CorsPolicy());
- var mockOptions = new Mock>();
- mockOptions.SetupGet(o => o.Options)
- .Returns(corsOptions);
- var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
- authorizationOptions: null);
- var typeInfo = typeof(CorsController).GetTypeInfo();
-
- // Act
- var model = builder.BuildControllerModel(typeInfo);
-
- // Assert
- Assert.Single(model.Filters, f => f is CorsAuthorizationFilterFactory);
- }
-
- [Fact]
- public void BuildControllerModel_AddsControllerProperties()
- {
- // Arrange
- var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null), null);
- var typeInfo = typeof(ModelBinderController).GetTypeInfo();
-
- // Act
- var model = builder.BuildControllerModel(typeInfo);
-
- // Assert
- Assert.Equal(2, model.ControllerProperties.Count);
- Assert.Equal("Bound", model.ControllerProperties[0].PropertyName);
- Assert.Equal(BindingSource.Query, model.ControllerProperties[0].BindingInfo.BindingSource);
- Assert.NotNull(model.ControllerProperties[0].Controller);
- var attribute = Assert.Single(model.ControllerProperties[0].Attributes);
- Assert.IsType(attribute);
- }
-
- [Fact]
- public void BuildControllerModel_DisableCorsAttributeAddsDisableCorsAuthorizationFilter()
- {
- // Arrange
- var corsOptions = new CorsOptions();
- corsOptions.AddPolicy("policy", new CorsPolicy());
- var mockOptions = new Mock>();
- mockOptions.SetupGet(o => o.Options)
- .Returns(corsOptions);
- var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null),
- authorizationOptions: null);
- var typeInfo = typeof(DisableCorsController).GetTypeInfo();
-
- // Act
- var model = builder.BuildControllerModel(typeInfo);
-
- // Assert
- Assert.True(model.Filters.Any(f => f is DisableCorsAuthorizationFilter));
- }
-
- // This class has a filter attribute, but doesn't implement any filter interfaces,
- // so ControllerFilter is not present.
- [Fact]
- public void BuildControllerModel_ClassWithoutFilterInterfaces_HasNoControllerFilter()
- {
- // Arrange
- var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null), null);
- var typeInfo = typeof(NoFiltersController).GetTypeInfo();
-
- // Act
- var model = builder.BuildControllerModel(typeInfo);
-
- // Assert
- var filter = Assert.Single(model.Filters);
- Assert.IsType(filter);
- }
-
- [Fact]
- public void BuildControllerModel_ClassWithFilterInterfaces_HasFilter()
- {
- // Arrange
- var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null), null);
- var typeInfo = typeof(SomeFiltersController).GetTypeInfo();
-
- // Act
- var model = builder.BuildControllerModel(typeInfo);
-
- // Assert
- Assert.Single(model.Filters, f => f is ControllerActionFilter);
- Assert.Single(model.Filters, f => f is ControllerResultFilter);
- }
-
- [Fact]
- public void BuildControllerModel_ClassWithFilterInterfaces_UnsupportedType()
- {
- // Arrange
- var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null), null);
- var typeInfo = typeof(UnsupportedFiltersController).GetTypeInfo();
-
- // Act
- var model = builder.BuildControllerModel(typeInfo);
-
- // Assert
- Assert.Empty(model.Filters);
- }
-
- [Fact]
- public void BuildControllerModel_ClassWithInheritedRoutes()
- {
- // Arrange
- var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null), null);
- var typeInfo = typeof(DerivedClassInheritingRoutesController).GetTypeInfo();
-
- // Act
- var model = builder.BuildControllerModel(typeInfo);
-
- // Assert
- Assert.Equal(2, model.AttributeRoutes.Count);
- Assert.Equal(2, model.Attributes.Count);
-
- var route = Assert.Single(model.AttributeRoutes, r => r.Template == "A");
- Assert.Contains(route.Attribute, model.Attributes);
-
- route = Assert.Single(model.AttributeRoutes, r => r.Template == "B");
- Assert.Contains(route.Attribute, model.Attributes);
- }
-
- [Fact]
- public void BuildControllerModel_ClassWithHiddenInheritedRoutes()
- {
- // Arrange
- var builder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null), null);
- var typeInfo = typeof(DerivedClassHidingRoutesController).GetTypeInfo();
-
- // Act
- var model = builder.BuildControllerModel(typeInfo);
-
- // Assert
- Assert.Equal(2, model.AttributeRoutes.Count);
- Assert.Equal(2, model.Attributes.Count);
-
- var route = Assert.Single(model.AttributeRoutes, r => r.Template == "C");
- Assert.Contains(route.Attribute, model.Attributes);
-
- route = Assert.Single(model.AttributeRoutes, r => r.Template == "D");
- Assert.Contains(route.Attribute, model.Attributes);
- }
-
- [Route("A")]
- [Route("B")]
- private class BaseClassWithRoutesController
- {
- }
-
- private class DerivedClassInheritingRoutesController : BaseClassWithRoutesController
- {
- }
-
- [Route("C")]
- [Route("D")]
- private class DerivedClassHidingRoutesController : BaseClassWithRoutesController
- {
- }
-
- private class StoreController : Mvc.Controller
- {
- }
-
- [Produces("application/json")]
- public class NoFiltersController
- {
- }
-
- [Authorize]
- public class AccountController
- {
- }
-
- [EnableCors("policy")]
- public class CorsController
- {
- }
-
- [DisableCors]
- public class DisableCorsController
- {
- }
-
- public class ModelBinderController
- {
- [FromQuery]
- public string Bound { get; set; }
-
- public string Unbound { get; set; }
- }
-
- public class SomeFiltersController : IAsyncActionFilter, IResultFilter
- {
- public Task OnActionExecutionAsync(
- [NotNull] ActionExecutingContext context,
- [NotNull] ActionExecutionDelegate next)
- {
- return null;
- }
-
- public void OnResultExecuted([NotNull] ResultExecutedContext context)
- {
- }
-
- public void OnResultExecuting([NotNull]ResultExecutingContext context)
- {
- }
- }
-
- private class UnsupportedFiltersController : IExceptionFilter, IAuthorizationFilter, IAsyncResourceFilter
- {
- public void OnAuthorization([NotNull]AuthorizationContext context)
- {
- throw new NotImplementedException();
- }
-
- public void OnException([NotNull]ExceptionContext context)
- {
- throw new NotImplementedException();
- }
-
- public Task OnResourceExecutionAsync([NotNull]ResourceExecutingContext context, [NotNull]ResourceExecutionDelegate next)
- {
- throw new NotImplementedException();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ControllerActionDescriptorProviderTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ControllerActionDescriptorProviderTests.cs
index f9f6cdf502..4515f0ef7e 100644
--- a/test/Microsoft.AspNet.Mvc.Core.Test/ControllerActionDescriptorProviderTests.cs
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/ControllerActionDescriptorProviderTests.cs
@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
+using Microsoft.AspNet.Authorization;
using Microsoft.AspNet.Mvc.ApiExplorer;
using Microsoft.AspNet.Mvc.ApplicationModels;
using Microsoft.AspNet.Mvc.Core;
@@ -1449,61 +1450,63 @@ namespace Microsoft.AspNet.Mvc.Test
TypeInfo controllerTypeInfo,
IEnumerable filters = null)
{
+ var options = new MockMvcOptionsAccessor();
+ if (filters != null)
+ {
+ foreach (var filter in filters)
+ {
+ options.Options.Filters.Add(filter);
+ }
+ }
+
var controllerTypeProvider = new FixedSetControllerTypeProvider(new[] { controllerTypeInfo });
- var controllerModelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null), null);
+ var modelProvider = new DefaultApplicationModelProvider(options, new MockAuthorizationOptionsAccessor());
var provider = new ControllerActionDescriptorProvider(
controllerTypeProvider,
- controllerModelBuilder,
- new TestGlobalFilterProvider(filters),
- new MockMvcOptionsAccessor());
+ new[] { modelProvider },
+ options);
return provider;
}
private ControllerActionDescriptorProvider GetProvider(
- params TypeInfo[] controllerTypeInfo)
+ params TypeInfo[] controllerTypeInfos)
{
- var controllerTypeProvider = new FixedSetControllerTypeProvider(controllerTypeInfo);
- var controllerModelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null), null);
+ var options = new MockMvcOptionsAccessor();
+
+ var controllerTypeProvider = new FixedSetControllerTypeProvider(controllerTypeInfos);
+ var modelProvider = new DefaultApplicationModelProvider(options, new MockAuthorizationOptionsAccessor());
var provider = new ControllerActionDescriptorProvider(
controllerTypeProvider,
- controllerModelBuilder,
- new TestGlobalFilterProvider(),
- new MockMvcOptionsAccessor());
+ new[] { modelProvider },
+ options);
return provider;
}
private ControllerActionDescriptorProvider GetProvider(
- TypeInfo type,
+ TypeInfo controllerTypeInfo,
IApplicationModelConvention convention)
{
- var controllerTypeProvider = new FixedSetControllerTypeProvider(new[] { type });
- var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null), null);
-
var options = new MockMvcOptionsAccessor();
options.Options.Conventions.Add(convention);
- return new ControllerActionDescriptorProvider(
+ var controllerTypeProvider = new FixedSetControllerTypeProvider(new[] { controllerTypeInfo });
+ var modelProvider = new DefaultApplicationModelProvider(options, new MockAuthorizationOptionsAccessor());
+
+ var provider = new ControllerActionDescriptorProvider(
controllerTypeProvider,
- modelBuilder,
- new TestGlobalFilterProvider(),
+ new[] { modelProvider },
options);
+
+ return provider;
}
private IEnumerable GetDescriptors(params TypeInfo[] controllerTypeInfos)
{
- var controllerTypeProvider = new FixedSetControllerTypeProvider(controllerTypeInfos);
- var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null), null);
-
- var provider = new ControllerActionDescriptorProvider(
- controllerTypeProvider,
- modelBuilder,
- new TestGlobalFilterProvider(),
- new MockMvcOptionsAccessor());
-
+ var provider = GetProvider(controllerTypeInfos);
return provider.GetDescriptors();
}
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/DefaultActionSelectorTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/DefaultActionSelectorTests.cs
index ec737dd61f..f428de3188 100644
--- a/test/Microsoft.AspNet.Mvc.Core.Test/DefaultActionSelectorTests.cs
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/DefaultActionSelectorTests.cs
@@ -7,6 +7,7 @@ using System.ComponentModel.Design;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
+using Microsoft.AspNet.Authorization;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Internal;
using Microsoft.AspNet.Mvc.ActionConstraints;
@@ -667,14 +668,17 @@ namespace Microsoft.AspNet.Mvc
.Select(t => t.GetTypeInfo())
.ToList();
- var controllerTypeProvider = new FixedSetControllerTypeProvider(controllerTypes);
- var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null), null);
+ var options = new MockMvcOptionsAccessor();
- return new ControllerActionDescriptorProvider(
- controllerTypeProvider,
- modelBuilder,
- new TestGlobalFilterProvider(),
- new MockMvcOptionsAccessor());
+ var controllerTypeProvider = new FixedSetControllerTypeProvider(controllerTypes);
+ var modelProvider = new DefaultApplicationModelProvider(options, new MockAuthorizationOptionsAccessor());
+
+ var provider = new ControllerActionDescriptorProvider(
+ controllerTypeProvider,
+ new[] { modelProvider },
+ options);
+
+ return provider;
}
private static HttpContext GetHttpContext(string httpMethod)
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/MockAuthorizationOptionsAccessor.cs b/test/Microsoft.AspNet.Mvc.Core.Test/MockAuthorizationOptionsAccessor.cs
new file mode 100644
index 0000000000..b17c0902a5
--- /dev/null
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/MockAuthorizationOptionsAccessor.cs
@@ -0,0 +1,17 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.Framework.OptionsModel;
+
+namespace Microsoft.AspNet.Authorization
+{
+ public class MockAuthorizationOptionsAccessor : IOptions
+ {
+ public AuthorizationOptions Options { get; } = new AuthorizationOptions();
+
+ public AuthorizationOptions GetNamedOptions(string name)
+ {
+ return Options;
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/TestGlobalFilterProvider.cs b/test/Microsoft.AspNet.Mvc.Core.Test/TestGlobalFilterProvider.cs
deleted file mode 100644
index fb18e50b8b..0000000000
--- a/test/Microsoft.AspNet.Mvc.Core.Test/TestGlobalFilterProvider.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Collections.Generic;
-using Microsoft.AspNet.Mvc.Filters;
-
-namespace Microsoft.AspNet.Mvc
-{
- public class TestGlobalFilterProvider : IGlobalFilterProvider
- {
- public TestGlobalFilterProvider()
- : this(null)
- {
- }
-
- public TestGlobalFilterProvider(IEnumerable filters)
- {
- var filterList = new List();
- Filters = filterList;
-
- if (filters != null)
- {
- filterList.AddRange(filters);
- }
- }
-
- public IReadOnlyList Filters { get; private set; }
- }
-}
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Mvc.Test/MvcServiceCollectionExtensionsTest.cs b/test/Microsoft.AspNet.Mvc.Test/MvcServiceCollectionExtensionsTest.cs
index 8772d6a874..68b6ca879d 100644
--- a/test/Microsoft.AspNet.Mvc.Test/MvcServiceCollectionExtensionsTest.cs
+++ b/test/Microsoft.AspNet.Mvc.Test/MvcServiceCollectionExtensionsTest.cs
@@ -7,6 +7,7 @@ using System.Linq;
using System.Reflection;
using Microsoft.AspNet.Mvc.ActionConstraints;
using Microsoft.AspNet.Mvc.ApiExplorer;
+using Microsoft.AspNet.Mvc.ApplicationModels;
using Microsoft.AspNet.Mvc.Core;
using Microsoft.AspNet.Mvc.MvcServiceCollectionExtensionsTestControllers;
using Microsoft.AspNet.Mvc.Razor;
@@ -140,7 +141,8 @@ namespace Microsoft.AspNet.Mvc
typeof(IActionDescriptorProvider),
typeof(IActionInvokerProvider),
typeof(IFilterProvider),
- typeof(IApiDescriptionProvider)
+ typeof(IApiDescriptionProvider),
+ typeof(IApplicationModelProvider),
};
}
}
diff --git a/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ApiControllerActionDiscoveryTest.cs b/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ApiControllerActionDiscoveryTest.cs
index 86aa5e69c8..7e38e9a8e4 100644
--- a/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ApiControllerActionDiscoveryTest.cs
+++ b/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ApiControllerActionDiscoveryTest.cs
@@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
+using Microsoft.AspNet.Authorization;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.ApplicationModels;
using Microsoft.AspNet.Mvc.Core;
@@ -372,12 +373,6 @@ namespace System.Web.Http
var assemblyProvider = new FixedSetAssemblyProvider();
assemblyProvider.CandidateAssemblies.Add(GetType().GetTypeInfo().Assembly);
var controllerTypeProvider = new NamespaceFilteredControllerTypeProvider(assemblyProvider);
- var modelBuilder = new DefaultControllerModelBuilder(new DefaultActionModelBuilder(null), null);
-
- var filterProvider = new Mock();
- filterProvider
- .SetupGet(fp => fp.Filters)
- .Returns(new List());
var options = new MvcOptions();
@@ -389,10 +384,18 @@ namespace System.Web.Http
.SetupGet(o => o.Options)
.Returns(options);
+ var authorizationOptionsAccessor = new Mock>();
+ authorizationOptionsAccessor
+ .SetupGet(o => o.Options)
+ .Returns(new AuthorizationOptions());
+
+ var modelProvider = new DefaultApplicationModelProvider(
+ optionsAccessor.Object,
+ authorizationOptionsAccessor.Object);
+
var provider = new ControllerActionDescriptorProvider(
controllerTypeProvider,
- modelBuilder,
- filterProvider.Object,
+ new[] { modelProvider },
optionsAccessor.Object);
return provider;