diff --git a/src/AttributeRouting.Tests.Web/AttributeRouting.Tests.Web.csproj b/src/AttributeRouting.Tests.Web/AttributeRouting.Tests.Web.csproj index 145b078..24eca05 100644 --- a/src/AttributeRouting.Tests.Web/AttributeRouting.Tests.Web.csproj +++ b/src/AttributeRouting.Tests.Web/AttributeRouting.Tests.Web.csproj @@ -35,6 +35,7 @@ + true true @@ -230,6 +231,9 @@ AttributeRouting + + + 10.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) diff --git a/src/AttributeRouting.Tests.Web/Controllers/ApiExplorerController.cs b/src/AttributeRouting.Tests.Web/Controllers/ApiExplorerController.cs index e157b95..a11abac 100644 --- a/src/AttributeRouting.Tests.Web/Controllers/ApiExplorerController.cs +++ b/src/AttributeRouting.Tests.Web/Controllers/ApiExplorerController.cs @@ -1,5 +1,5 @@ -using System.Web.Http; -using System.Web.Mvc; +using System.Web.Mvc; +using System.Web.Http; using AttributeRouting.Web.Http; namespace AttributeRouting.Tests.Web.Controllers @@ -8,7 +8,8 @@ namespace AttributeRouting.Tests.Web.Controllers public class ApiExplorerController : Controller { [GET("")] - public ActionResult Index() + [System.Web.Mvc.ActionName("Index")] + public ActionResult Index101() { var explorer = GlobalConfiguration.Configuration.Services.GetApiExplorer(); return View(explorer); diff --git a/src/AttributeRouting.Tests.Web/Views/ApiExplorer/Index1.cshtml b/src/AttributeRouting.Tests.Web/Views/ApiExplorer/Index1.cshtml new file mode 100644 index 0000000..2baa2d6 --- /dev/null +++ b/src/AttributeRouting.Tests.Web/Views/ApiExplorer/Index1.cshtml @@ -0,0 +1,34 @@ +@model System.Web.Http.Description.IApiExplorer + +@{ + Layout = null; +} + + + + + + API Explorer (Index 1) + + + +
+
    + @foreach (var api in Model.ApiDescriptions) + { +
  • + @api.HttpMethod @api.RelativePath + @foreach(var param in api.ParameterDescriptions) + { +

    Parameter: @param.Name (@param.Source)

    + } +
  • + } +
+
+ + \ No newline at end of file diff --git a/src/AttributeRouting.Web.Mvc/RouteAttribute.cs b/src/AttributeRouting.Web.Mvc/RouteAttribute.cs index 7f73314..097d070 100644 --- a/src/AttributeRouting.Web.Mvc/RouteAttribute.cs +++ b/src/AttributeRouting.Web.Mvc/RouteAttribute.cs @@ -3,6 +3,7 @@ using System.Reflection; using System.Web.Mvc; using AttributeRouting.Helpers; +using System.Collections.Generic; namespace AttributeRouting.Web.Mvc { @@ -12,6 +13,15 @@ namespace AttributeRouting.Web.Mvc [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] public class RouteAttribute : ActionMethodSelectorAttribute, IRouteAttribute { + //private static readonly SortedSet Members = + // new SortedSet( + // typeof(RouteAttribute).GetProperties() + // .Where(p => p.CanRead) + // .Select(p => p.Name), + // StringComparer.CurrentCultureIgnoreCase); + + //private static readonly FastMember.TypeAccessor Accessor = FastMember.TypeAccessor.Create(typeof(RouteAttribute)); + /// /// Specify the route information for an action. /// The route URL will be the name of the action. @@ -132,5 +142,17 @@ public override bool IsValidForRequest(ControllerContext controllerContext, Meth return HttpMethods.Any(m => m.ValueEquals(httpMethod)); } + + public string ActionName { get; set; } + + //public object this[string name] + //{ + // get + // { + // if(Members.Contains(name)) + // { return Accessor[this, name]; } + // return null; + // } + //} } } \ No newline at end of file diff --git a/src/AttributeRouting.sln b/src/AttributeRouting.sln index 99fb999..7e100cc 100644 --- a/src/AttributeRouting.sln +++ b/src/AttributeRouting.sln @@ -1,6 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 +# Visual Studio 2013 +VisualStudioVersion = 12.0.20827.3 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{38404E6F-56AC-458E-B0A6-3620FEA10A5C}" ProjectSection(SolutionItems) = preProject .nuget\NuGet.Config = .nuget\NuGet.Config @@ -34,10 +36,6 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AttributeRouting.Web.Http", "AttributeRouting.Web.Http\AttributeRouting.Web.Http.csproj", "{CCDE9AD7-3822-4B0B-AA19-DF6698A85D3D}" EndProject Global - GlobalSection(SubversionScc) = preSolution - Svn-Managed = True - Manager = AnkhSVN - Subversion Support for Visual Studio - EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|Mixed Platforms = Debug|Mixed Platforms @@ -146,4 +144,8 @@ Global {486087C6-E95B-4FE2-8263-7B6B2DF81888} = {840281A8-8870-417F-9B24-ED0E866608A2} {0D2A13E6-A092-402E-B8FE-035F3A620B86} = {840281A8-8870-417F-9B24-ED0E866608A2} EndGlobalSection + GlobalSection(SubversionScc) = preSolution + Svn-Managed = True + Manager = AnkhSVN - Subversion Support for Visual Studio + EndGlobalSection EndGlobal diff --git a/src/AttributeRouting/AttributeRouting.csproj b/src/AttributeRouting/AttributeRouting.csproj index c591f85..be0c843 100644 --- a/src/AttributeRouting/AttributeRouting.csproj +++ b/src/AttributeRouting/AttributeRouting.csproj @@ -51,6 +51,12 @@ AttributeRouting.snk + + ..\packages\FastMember.Signed.1.0.0.11\lib\net40\FastMember.dll + + + ..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll + @@ -119,6 +125,7 @@ + diff --git a/src/AttributeRouting/Framework/AttributeReflector.cs b/src/AttributeRouting/Framework/AttributeReflector.cs index 7b18ffb..9faf732 100644 --- a/src/AttributeRouting/Framework/AttributeReflector.cs +++ b/src/AttributeRouting/Framework/AttributeReflector.cs @@ -2,7 +2,8 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; -using AttributeRouting.Helpers; +using AttributeRouting.Helpers; +using System.Diagnostics; namespace AttributeRouting.Framework { @@ -29,7 +30,7 @@ public IEnumerable BuildRouteSpecifications() var controllerCount = 0; // needed to increment controller index var inheritActionsFromBaseController = _configuration.InheritActionsFromBaseController; - var specs = + var specs = ( // Each controller from controllerType in _configuration.OrderedControllerTypes let controllerIndex = controllerCount++ @@ -50,7 +51,7 @@ from routePrefixAttribute in routePrefixAttributes.DefaultIfEmpty(null).Take(rou // Build the specification select new RouteSpecification { - ActionMethod = actionMethod, + ActionMethod = actionMethod, ActionName = actionName, ActionPrecedence = GetSortableOrder(routeAttribute.ActionPrecedence), AppendTrailingSlash = routeAttribute.AppendTrailingSlashFlag, @@ -69,13 +70,13 @@ from routePrefixAttribute in routePrefixAttributes.DefaultIfEmpty(null).Take(rou PreserveCaseForUrlParameters = routeAttribute.PreserveCaseForUrlParametersFlag, RouteName = routeAttribute.RouteName, RoutePrefixUrl = GetRoutePrefixUrl(routePrefixAttribute, controllerType), - RoutePrefixUrlTranslationKey = routePrefixAttribute.SafeGet(a => a.TranslationKey), + RoutePrefixUrlTranslationKey = routePrefixAttribute.SafeGet(a => a.TranslationKey), RouteUrl = routeAttribute.RouteUrl ?? actionName, RouteUrlTranslationKey = routeAttribute.TranslationKey, SitePrecedence = GetSortableOrder(routeAttribute.SitePrecedence), Subdomain = subdomain, UseLowercaseRoute = routeAttribute.UseLowercaseRouteFlag, - }; + }).ToArray(); // Return specs ordered by route precedence: return specs.OrderBy(x => x.SitePrecedence) @@ -83,18 +84,20 @@ from routePrefixAttribute in routePrefixAttributes.DefaultIfEmpty(null).Take(rou .ThenBy(x => x.PrefixPrecedence) .ThenBy(x => x.ControllerPrecedence) .ThenBy(x => x.ActionPrecedence); - } - - private static string GetActionName(MethodInfo actionMethod, bool isAsyncController) - { - var actionName = actionMethod.Name; - - if (isAsyncController && actionName.EndsWith("Async")) - { - actionName = actionName.Substring(0, actionName.Length - 5); - } - - return actionName; + } + + private static string GetActionName(MethodInfo actionMethod, bool isAsyncController) + { + // added support for ActionName attribute + var anAttribute = actionMethod.GetCustomAttributes(false).FirstOrDefault(a => a.GetType().Name == "ActionNameAttribute"); + var actionName = anAttribute == null ? actionMethod.Name : (string)FastMember.ObjectAccessor.Create(anAttribute)["Name"]; + + if (isAsyncController && actionName.EndsWith("Async")) + { + actionName = actionName.Substring(0, actionName.Length - 5); + } + + return actionName; } private static IEnumerable GetRouteAttributes(MethodInfo actionMethod, RouteConventionAttributeBase convention) diff --git a/src/AttributeRouting/packages.config b/src/AttributeRouting/packages.config new file mode 100644 index 0000000..3d0b8f4 --- /dev/null +++ b/src/AttributeRouting/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file