From 1536daa1075c2de2e879ce615e9ea2bb9a76c5b0 Mon Sep 17 00:00:00 2001 From: harshgMSFT Date: Wed, 9 Apr 2014 18:10:49 -0700 Subject: [PATCH] Adding NonAction Attribute --- .../DefaultActionDiscoveryConventions.cs | 3 +- .../NonActionAttribute.cs | 9 +++++ .../ActionAttributeTests.cs | 40 +++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/Microsoft.AspNet.Mvc.Core/NonActionAttribute.cs diff --git a/src/Microsoft.AspNet.Mvc.Core/DefaultActionDiscoveryConventions.cs b/src/Microsoft.AspNet.Mvc.Core/DefaultActionDiscoveryConventions.cs index f9b45204aa..52a35ecd80 100644 --- a/src/Microsoft.AspNet.Mvc.Core/DefaultActionDiscoveryConventions.cs +++ b/src/Microsoft.AspNet.Mvc.Core/DefaultActionDiscoveryConventions.cs @@ -86,7 +86,8 @@ namespace Microsoft.AspNet.Mvc // The SpecialName bit is set to flag members that are treated in a special way by some compilers // (such as property accessors and operator overloading methods). - !method.IsSpecialName; + !method.IsSpecialName && + !method.IsDefined(typeof(NonActionAttribute)); } public virtual IEnumerable GetSupportedHttpMethods(MethodInfo methodInfo) diff --git a/src/Microsoft.AspNet.Mvc.Core/NonActionAttribute.cs b/src/Microsoft.AspNet.Mvc.Core/NonActionAttribute.cs new file mode 100644 index 0000000000..7e9404b8c6 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/NonActionAttribute.cs @@ -0,0 +1,9 @@ +using System; + +namespace Microsoft.AspNet.Mvc +{ + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] + public sealed class NonActionAttribute : Attribute + { + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ActionAttributeTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ActionAttributeTests.cs index 97b0fefef2..32d5f84236 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ActionAttributeTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ActionAttributeTests.cs @@ -5,6 +5,7 @@ using Microsoft.AspNet.DependencyInjection.NestedProviders; using Moq; using System; using System.Collections.Generic; +using System.Linq; using System.Reflection; using System.Threading.Tasks; using Xunit; @@ -108,6 +109,26 @@ namespace Microsoft.AspNet.Mvc.Core.Test Assert.Equal("Index", result.Name); } + [Theory] + [InlineData("Put")] + [InlineData("RPCMethod")] + [InlineData("RPCMethodWithHttpGet")] + public async Task NonActionAttribute_ActionNotReachable(string actionName) + { + // Arrange + var actionDescriptorProvider = GetActionDescriptorProvider(_actionDiscoveryConventions); + + // Act + var result = actionDescriptorProvider.GetDescriptors() + .Select(x => x as ReflectedActionDescriptor) + .FirstOrDefault( + x=> x.ControllerName == "NonAction" && + x.Name == actionName); + + // Assert + Assert.Null(result); + } + [Theory] [InlineData("GET")] [InlineData("PUT")] @@ -220,6 +241,25 @@ namespace Microsoft.AspNet.Mvc.Core.Test #region Controller Classes + private class NonActionController + { + [NonAction] + public void Put() + { + } + + [NonAction] + public void RPCMethod() + { + } + + [NonAction] + [HttpGet] + public void RPCMethodWithHttpGet() + { + } + } + private class HttpMethodAttributeTests_DefaultMethodValidationController { public void Index()