diff --git a/src/Microsoft.AspNet.Mvc.Core/DefaultActionDiscoveryConventions.cs b/src/Microsoft.AspNet.Mvc.Core/DefaultActionDiscoveryConventions.cs index 1017ff50a0..ff99697e4a 100644 --- a/src/Microsoft.AspNet.Mvc.Core/DefaultActionDiscoveryConventions.cs +++ b/src/Microsoft.AspNet.Mvc.Core/DefaultActionDiscoveryConventions.cs @@ -79,10 +79,16 @@ namespace Microsoft.AspNet.Mvc return String.Equals(methodInfo.Name, DefaultMethodName, StringComparison.OrdinalIgnoreCase); } + /// + /// Determines whether the method is a valid action. + /// + /// The . + /// true if the method is a valid action. Otherwise, false. protected virtual bool IsValidActionMethod(MethodInfo method) { return method.IsPublic && + !method.IsStatic && !method.IsAbstract && !method.IsConstructor && !method.IsGenericMethod && diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedActionDescriptorProviderTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedActionDescriptorProviderTests.cs index 5ab6c62544..7dde64e739 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedActionDescriptorProviderTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedActionDescriptorProviderTests.cs @@ -34,7 +34,7 @@ namespace Microsoft.AspNet.Mvc var actionNames = GetDescriptors(typeof(BaseController).GetTypeInfo()).Select(a => a.Name); // Assert - Assert.False(actionNames.Contains("Redirect")); + Assert.DoesNotContain("Redirect", actionNames); } [Fact] @@ -44,7 +44,7 @@ namespace Microsoft.AspNet.Mvc var actionNames = GetActionNamesFromDerivedController(); // Assert - Assert.False(actionNames.Contains("PrivateMethod")); + Assert.DoesNotContain("PrivateMethod", actionNames); } [Fact] @@ -54,7 +54,7 @@ namespace Microsoft.AspNet.Mvc var actionNames = GetActionNamesFromDerivedController(); // Assert - Assert.False(actionNames.Contains("DerivedController")); + Assert.DoesNotContain("DerivedController", actionNames); } [Fact] @@ -74,7 +74,7 @@ namespace Microsoft.AspNet.Mvc var actionNames = GetActionNamesFromDerivedController(); // Assert - Assert.False(actionNames.Contains("GenericMethod")); + Assert.DoesNotContain("GenericMethod", actionNames); } [Fact] @@ -84,7 +84,7 @@ namespace Microsoft.AspNet.Mvc var actionNames = GetActionNamesFromDerivedController(); // Assert - Assert.False(actionNames.Contains("OverridenNonActionMethod")); + Assert.DoesNotContain("OverridenNonActionMethod", actionNames); } [Fact] @@ -100,6 +100,36 @@ namespace Microsoft.AspNet.Mvc Assert.Empty(methodsFromObjectClass.Intersect(actionNames)); } + [Fact] + public void GetDescriptors_Ignores_StaticMethod_FromUserDefinedController() + { + // Arrange & Act + var actionNames = GetActionNamesFromDerivedController(); + + // Assert + Assert.DoesNotContain("StaticMethod", actionNames); + } + + [Fact] + public void GetDescriptors_Ignores_ProtectedStaticMethod_FromUserDefinedController() + { + // Arrange & Act + var actionNames = GetActionNamesFromDerivedController(); + + // Assert + Assert.DoesNotContain("ProtectedStaticMethod", actionNames); + } + + [Fact] + public void GetDescriptors_Ignores_PrivateStaticMethod_FromUserDefinedController() + { + // Arrange & Act + var actionNames = GetActionNamesFromDerivedController(); + + // Assert + Assert.DoesNotContain("PrivateStaticMethod", actionNames); + } + private IEnumerable GetActionNamesFromDerivedController() { return GetDescriptors(typeof(DerivedController).GetTypeInfo()).Select(a => a.Name); @@ -143,6 +173,18 @@ namespace Microsoft.AspNet.Mvc private void PrivateMethod() { } + + public static void StaticMethod() + { + } + + protected static void ProtectedStaticMethod() + { + } + + private static void PrivateStaticMethod() + { + } } private class OperatorOverloadingController : Controller