diff --git a/src/Microsoft.AspNet.Mvc.Core/ApplicationModelConventionExtensions.cs b/src/Microsoft.AspNet.Mvc.Core/ApplicationModelConventionExtensions.cs
new file mode 100644
index 0000000000..3ff98df64c
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.Core/ApplicationModelConventionExtensions.cs
@@ -0,0 +1,93 @@
+// 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.
+
+using System.Collections.Generic;
+using Microsoft.AspNet.Mvc.ApplicationModels;
+
+namespace Microsoft.AspNet.Mvc
+{
+ ///
+ /// Contains the extension methods for .
+ ///
+ public static class ApplicationModelConventionExtensions
+ {
+ ///
+ /// Adds a to all the controllers in the application.
+ ///
+ /// The list of
+ /// in .
+ /// The which needs to be
+ /// added.
+ public static void Add(
+ [NotNull] this List conventions,
+ [NotNull] IControllerModelConvention controllerModelConvention)
+ {
+ conventions.Add(new ControllerApplicationModelConvention(controllerModelConvention));
+ }
+
+ ///
+ /// Adds a to all the actions in the application.
+ ///
+ /// The list of
+ /// in .
+ /// The which needs to be
+ /// added.
+ public static void Add(
+ this List conventions,
+ IActionModelConvention actionModelConvention)
+ {
+ conventions.Add(new ActionApplicationModelConvention(actionModelConvention));
+ }
+
+ private class ActionApplicationModelConvention : IApplicationModelConvention
+ {
+ private IActionModelConvention _actionModelConvention;
+
+ ///
+ /// Initializes a new instance of .
+ ///
+ /// The action convention to be applied on all actions
+ /// in the application.
+ public ActionApplicationModelConvention([NotNull] IActionModelConvention actionModelConvention)
+ {
+ _actionModelConvention = actionModelConvention;
+ }
+
+ ///
+ public void Apply([NotNull] ApplicationModel application)
+ {
+ foreach (var controller in application.Controllers)
+ {
+ foreach (var action in controller.Actions)
+ {
+ _actionModelConvention.Apply(action);
+ }
+ }
+ }
+ }
+
+ private class ControllerApplicationModelConvention : IApplicationModelConvention
+ {
+ private IControllerModelConvention _controllerModelConvention;
+
+ ///
+ /// Initializes a new instance of .
+ ///
+ /// The controller convention to be applied on all controllers
+ /// in the application.
+ public ControllerApplicationModelConvention([NotNull] IControllerModelConvention controllerConvention)
+ {
+ _controllerModelConvention = controllerConvention;
+ }
+
+ ///
+ public void Apply([NotNull] ApplicationModel application)
+ {
+ foreach (var controller in application.Controllers)
+ {
+ _controllerModelConvention.Apply(controller);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/IApplicationModelConvention.cs b/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/IApplicationModelConvention.cs
index ea746a6074..5fabf2d292 100644
--- a/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/IApplicationModelConvention.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/ApplicationModels/IApplicationModelConvention.cs
@@ -7,7 +7,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
/// Allows customization of the of the .
///
///
- /// Implementaions of this interface can be registered in
+ /// Implementaions of this interface can be registered in
/// to customize metadata about the application.
///
/// run before other types of customizations to the
diff --git a/src/Microsoft.AspNet.Mvc.Core/ControllerActionDescriptorProvider.cs b/src/Microsoft.AspNet.Mvc.Core/ControllerActionDescriptorProvider.cs
index cbc7cf575d..1e6b6589cf 100644
--- a/src/Microsoft.AspNet.Mvc.Core/ControllerActionDescriptorProvider.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/ControllerActionDescriptorProvider.cs
@@ -17,7 +17,7 @@ namespace Microsoft.AspNet.Mvc
private readonly IControllerModelBuilder _applicationModelBuilder;
private readonly IAssemblyProvider _assemblyProvider;
private readonly IReadOnlyList _globalFilters;
- private readonly IEnumerable _modelConventions;
+ private readonly IEnumerable _conventions;
private readonly ILogger _logger;
public ControllerActionDescriptorProvider([NotNull] IAssemblyProvider assemblyProvider,
@@ -29,7 +29,7 @@ namespace Microsoft.AspNet.Mvc
_assemblyProvider = assemblyProvider;
_applicationModelBuilder = applicationModelBuilder;
_globalFilters = globalFilters.Filters;
- _modelConventions = optionsAccessor.Options.ApplicationModelConventions;
+ _conventions = optionsAccessor.Options.Conventions;
_logger = loggerFactory.Create();
}
@@ -47,7 +47,7 @@ namespace Microsoft.AspNet.Mvc
public IEnumerable GetDescriptors()
{
var applicationModel = BuildModel();
- ApplicationModelConventions.ApplyConventions(applicationModel, _modelConventions);
+ ApplicationModelConventions.ApplyConventions(applicationModel, _conventions);
if (_logger.IsEnabled(LogLevel.Verbose))
{
foreach (var controller in applicationModel.Controllers)
diff --git a/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs b/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs
index 84588dadb0..3e84d7cc12 100644
--- a/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs
@@ -22,7 +22,7 @@ namespace Microsoft.AspNet.Mvc
public MvcOptions()
{
- ApplicationModelConventions = new List();
+ Conventions = new List();
ModelBinders = new List();
ViewEngines = new List();
ValueProviderFactories = new List();
@@ -133,7 +133,7 @@ namespace Microsoft.AspNet.Mvc
/// Gets a list of instances that will be applied to
/// the when discovering actions.
///
- public List ApplicationModelConventions { get; private set; }
+ public List Conventions { get; private set; }
///
/// Gets or sets the flag which causes content negotiation to ignore Accept header
diff --git a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/Conventions/WebApiActionConventionsApplicationModelConvention.cs b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/Conventions/WebApiActionConventionsApplicationModelConvention.cs
index 0f7b36016a..daefb57eb4 100644
--- a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/Conventions/WebApiActionConventionsApplicationModelConvention.cs
+++ b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/Conventions/WebApiActionConventionsApplicationModelConvention.cs
@@ -8,7 +8,7 @@ using Microsoft.AspNet.Mvc.ApplicationModels;
namespace Microsoft.AspNet.Mvc.WebApiCompatShim
{
- public class WebApiActionConventionsApplicationModelConvention : IApplicationModelConvention
+ public class WebApiActionConventionsApplicationModelConvention : IControllerModelConvention
{
private static readonly string[] SupportedHttpMethodConventions = new string[]
{
@@ -21,13 +21,31 @@ namespace Microsoft.AspNet.Mvc.WebApiCompatShim
"OPTIONS",
};
- public void Apply(ApplicationModel application)
+ public void Apply(ControllerModel controller)
{
- foreach (var controller in application.Controllers)
+ if (IsConventionApplicable(controller))
{
- if (IsConventionApplicable(controller))
+ var newActions = new List();
+
+ foreach (var action in controller.Actions)
{
- Apply(controller);
+ SetHttpMethodFromConvention(action);
+
+ // Action Name doesn't really come into play with attribute routed actions. However for a
+ // non-attribute-routed action we need to create a 'named' version and an 'unnamed' version.
+ if (!IsActionAttributeRouted(action))
+ {
+ var namedAction = action;
+
+ var unnamedAction = new ActionModel(namedAction);
+ unnamedAction.RouteConstraints.Add(new UnnamedActionRouteConstraint());
+ newActions.Add(unnamedAction);
+ }
+ }
+
+ foreach (var action in newActions)
+ {
+ controller.Actions.Add(action);
}
}
}
@@ -37,32 +55,6 @@ namespace Microsoft.AspNet.Mvc.WebApiCompatShim
return controller.Attributes.OfType().Any();
}
- private void Apply(ControllerModel controller)
- {
- var newActions = new List();
-
- foreach (var action in controller.Actions)
- {
- SetHttpMethodFromConvention(action);
-
- // Action Name doesn't really come into play with attribute routed actions. However for a
- // non-attribute-routed action we need to create a 'named' version and an 'unnamed' version.
- if (!IsActionAttributeRouted(action))
- {
- var namedAction = action;
-
- var unnamedAction = new ActionModel(namedAction);
- unnamedAction.RouteConstraints.Add(new UnnamedActionRouteConstraint());
- newActions.Add(unnamedAction);
- }
- }
-
- foreach (var action in newActions)
- {
- controller.Actions.Add(action);
- }
- }
-
private bool IsActionAttributeRouted(ActionModel action)
{
if (action.Controller.AttributeRoutes.Count > 0)
diff --git a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/Conventions/WebApiOverloadingApplicationModelConvention.cs b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/Conventions/WebApiOverloadingApplicationModelConvention.cs
index 6157100307..1f85d5f464 100644
--- a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/Conventions/WebApiOverloadingApplicationModelConvention.cs
+++ b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/Conventions/WebApiOverloadingApplicationModelConvention.cs
@@ -6,16 +6,13 @@ using Microsoft.AspNet.Mvc.ApplicationModels;
namespace Microsoft.AspNet.Mvc.WebApiCompatShim
{
- public class WebApiOverloadingApplicationModelConvention : IApplicationModelConvention
+ public class WebApiOverloadingApplicationModelConvention : IActionModelConvention
{
- public void Apply(ApplicationModel application)
+ public void Apply(ActionModel action)
{
- foreach (var controller in application.Controllers)
+ if (IsConventionApplicable(action.Controller))
{
- if (IsConventionApplicable(controller))
- {
- Apply(controller);
- }
+ action.ActionConstraints.Add(new OverloadActionConstraint());
}
}
@@ -23,13 +20,5 @@ namespace Microsoft.AspNet.Mvc.WebApiCompatShim
{
return controller.Attributes.OfType().Any();
}
-
- private void Apply(ControllerModel controller)
- {
- foreach (var action in controller.Actions)
- {
- action.ActionConstraints.Add(new OverloadActionConstraint());
- }
- }
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/Conventions/WebApiParameterConventionsApplicationModelConvention.cs b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/Conventions/WebApiParameterConventionsApplicationModelConvention.cs
index 117c7a85d1..2e6631c2e4 100644
--- a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/Conventions/WebApiParameterConventionsApplicationModelConvention.cs
+++ b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/Conventions/WebApiParameterConventionsApplicationModelConvention.cs
@@ -9,27 +9,11 @@ using Microsoft.AspNet.Mvc.ModelBinding;
namespace Microsoft.AspNet.Mvc.WebApiCompatShim
{
- public class WebApiParameterConventionsApplicationModelConvention : IApplicationModelConvention
+ public class WebApiParameterConventionsApplicationModelConvention : IActionModelConvention
{
- public void Apply(ApplicationModel application)
+ public void Apply(ActionModel action)
{
- foreach (var controller in application.Controllers)
- {
- if (IsConventionApplicable(controller))
- {
- Apply(controller);
- }
- }
- }
-
- private bool IsConventionApplicable(ControllerModel controller)
- {
- return controller.Attributes.OfType().Any();
- }
-
- private void Apply(ControllerModel controller)
- {
- foreach (var action in controller.Actions)
+ if (IsConventionApplicable(action.Controller))
{
foreach (var parameter in action.Parameters)
{
@@ -57,5 +41,10 @@ namespace Microsoft.AspNet.Mvc.WebApiCompatShim
}
}
}
+
+ private bool IsConventionApplicable(ControllerModel controller)
+ {
+ return controller.Attributes.OfType().Any();
+ }
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/Conventions/WebApiRoutesApplicationModelConvention.cs b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/Conventions/WebApiRoutesApplicationModelConvention.cs
index a01d91b9c3..61cbd7ab9a 100644
--- a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/Conventions/WebApiRoutesApplicationModelConvention.cs
+++ b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/Conventions/WebApiRoutesApplicationModelConvention.cs
@@ -6,7 +6,7 @@ using Microsoft.AspNet.Mvc.ApplicationModels;
namespace Microsoft.AspNet.Mvc.WebApiCompatShim
{
- public class WebApiRoutesApplicationModelConvention : IApplicationModelConvention
+ public class WebApiRoutesApplicationModelConvention : IControllerModelConvention
{
private readonly string _area;
@@ -15,14 +15,11 @@ namespace Microsoft.AspNet.Mvc.WebApiCompatShim
_area = area;
}
- public void Apply(ApplicationModel application)
+ public void Apply(ControllerModel controller)
{
- foreach (var controller in application.Controllers)
+ if (IsConventionApplicable(controller))
{
- if (IsConventionApplicable(controller))
- {
- Apply(controller);
- }
+ controller.RouteConstraints.Add(new AreaAttribute(_area));
}
}
@@ -30,10 +27,5 @@ namespace Microsoft.AspNet.Mvc.WebApiCompatShim
{
return controller.Attributes.OfType().Any();
}
-
- private void Apply(ControllerModel controller)
- {
- controller.RouteConstraints.Add(new AreaAttribute(_area));
- }
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/WebApiCompatShimOptionsSetup.cs b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/WebApiCompatShimOptionsSetup.cs
index e4f774386f..83fba7b4e9 100644
--- a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/WebApiCompatShimOptionsSetup.cs
+++ b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/WebApiCompatShimOptionsSetup.cs
@@ -22,10 +22,10 @@ namespace Microsoft.AspNet.Mvc.WebApiCompatShim
public void Configure(MvcOptions options, string name = "")
{
// Add webapi behaviors to controllers with the appropriate attributes
- options.ApplicationModelConventions.Add(new WebApiActionConventionsApplicationModelConvention());
- options.ApplicationModelConventions.Add(new WebApiParameterConventionsApplicationModelConvention());
- options.ApplicationModelConventions.Add(new WebApiOverloadingApplicationModelConvention());
- options.ApplicationModelConventions.Add(new WebApiRoutesApplicationModelConvention(area: DefaultAreaName));
+ options.Conventions.Add(new WebApiActionConventionsApplicationModelConvention());
+ options.Conventions.Add(new WebApiParameterConventionsApplicationModelConvention());
+ options.Conventions.Add(new WebApiOverloadingApplicationModelConvention());
+ options.Conventions.Add(new WebApiRoutesApplicationModelConvention(area: DefaultAreaName));
// Add an action filter for handling the HttpResponseException.
options.Filters.Add(new HttpResponseExceptionActionFilter());
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/ActionApplicationModelConventionTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/ActionApplicationModelConventionTest.cs
new file mode 100644
index 0000000000..bc1cb2e5d4
--- /dev/null
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/ActionApplicationModelConventionTest.cs
@@ -0,0 +1,59 @@
+// 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.
+
+using System.Collections.Generic;
+using System.Reflection;
+using Xunit;
+
+namespace Microsoft.AspNet.Mvc.ApplicationModels
+{
+ public class ActionApplicationModelConventionTest
+ {
+ [Fact]
+ public void DefaultActionModelConvention_AppliesToAllActionsInApp()
+ {
+ // Arrange
+ var options = new MvcOptions();
+ var app = new ApplicationModel();
+ app.Controllers.Add(new ControllerModel(typeof(HelloController).GetTypeInfo(), new List