diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionDescriptor.cs b/src/Microsoft.AspNet.Mvc.Core/ActionDescriptor.cs index 3b19745760..f7ffbdfa30 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionDescriptor.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionDescriptor.cs @@ -1,12 +1,18 @@ // 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; using System.Collections.Generic; namespace Microsoft.AspNet.Mvc { public class ActionDescriptor { + public ActionDescriptor() + { + RouteValueDefaults = new Dictionary(StringComparer.OrdinalIgnoreCase); + } + public virtual string Name { get; set; } public List RouteConstraints { get; set; } @@ -14,12 +20,12 @@ namespace Microsoft.AspNet.Mvc /// /// The set of route values that are added when this action is selected. /// - public Dictionary RouteValues { get; set; } + public Dictionary RouteValueDefaults { get; private set; } /// - /// The route template. May be null if the action has no attribute routes. + /// The attribute route template. May be null if the action has no attribute routes. /// - public string RouteTemplate { get; set; } + public string AttributeRouteTemplate { get; set; } public List MethodConstraints { get; set; } diff --git a/src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj b/src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj index a507eb91c8..da3a641a4c 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj +++ b/src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj @@ -217,7 +217,7 @@ - + diff --git a/src/Microsoft.AspNet.Mvc.Core/MvcRouteHandler.cs b/src/Microsoft.AspNet.Mvc.Core/MvcRouteHandler.cs index c9f3521a0e..0cc1cf8ff6 100644 --- a/src/Microsoft.AspNet.Mvc.Core/MvcRouteHandler.cs +++ b/src/Microsoft.AspNet.Mvc.Core/MvcRouteHandler.cs @@ -38,9 +38,9 @@ namespace Microsoft.AspNet.Mvc return; } - if (actionDescriptor.RouteValues != null) + if (actionDescriptor.RouteValueDefaults != null) { - foreach (var kvp in actionDescriptor.RouteValues) + foreach (var kvp in actionDescriptor.RouteValueDefaults) { if (!context.RouteData.Values.ContainsKey(kvp.Key)) { diff --git a/src/Microsoft.AspNet.Mvc.Core/ReflectedActionDescriptorProvider.cs b/src/Microsoft.AspNet.Mvc.Core/ReflectedActionDescriptorProvider.cs index af69f2a6bb..1d92526ed7 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ReflectedActionDescriptorProvider.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ReflectedActionDescriptorProvider.cs @@ -213,19 +213,17 @@ namespace Microsoft.AspNet.Mvc { // An attribute routed action will ignore conventional routed constraints. We still // want to provide these values as ambient values. - var ambientValues = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (var constraint in actionDescriptor.RouteConstraints) { - ambientValues.Add(constraint.RouteKey, constraint.RouteValue); + actionDescriptor.RouteValueDefaults.Add(constraint.RouteKey, constraint.RouteValue); } - actionDescriptor.RouteValues = ambientValues; - - // TODO #738 - this currently has parity with what we did in MVC5 when a template uses parameters - // like 'area', 'controller', and 'action. This needs to be reconsidered as part of #738. + // TODO #738 - this currently has parity with what we did in MVC5 when a template uses + // parameters like 'area', 'controller', and 'action. This needs to be changed as + // part of #738. // - // For instance, consider actions mapped with api/Blog/{action}. The value of {action} needs to - // passed to action selection to choose the right action. + // For instance, consider actions mapped with api/Blog/{action}. The value of {action} + // needs to passed to action selection to choose the right action. var template = TemplateParser.Parse(templateText, _constraintResolver); var routeConstraints = new List(); @@ -246,7 +244,7 @@ namespace Microsoft.AspNet.Mvc actionDescriptor.RouteConstraints = routeConstraints; - actionDescriptor.RouteTemplate = templateText; + actionDescriptor.AttributeRouteTemplate = templateText; } } @@ -265,7 +263,7 @@ namespace Microsoft.AspNet.Mvc { foreach (var key in removalConstraints) { - if (actionDescriptor.RouteTemplate == null) + if (actionDescriptor.AttributeRouteTemplate == null) { if (!HasConstraint(actionDescriptor.RouteConstraints, key)) { @@ -274,13 +272,6 @@ namespace Microsoft.AspNet.Mvc RouteKeyHandling.DenyKey)); } } - else - { - if (!actionDescriptor.RouteValues.ContainsKey(key)) - { - actionDescriptor.RouteValues.Add(key, null); - } - } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRoute.cs b/src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRoute.cs index a05ab1866d..c59df41737 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRoute.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRoute.cs @@ -17,7 +17,7 @@ namespace Microsoft.AspNet.Mvc.Routing { private readonly IRouter _next; private readonly TemplateRoute[] _matchingRoutes; - private readonly AttributeRouteGenerationEntry[] _generationEntries; + private readonly AttributeRouteLinkGenerationEntry[] _linkGenerationEntries; /// /// Creates a new . @@ -27,7 +27,7 @@ namespace Microsoft.AspNet.Mvc.Routing public AttributeRoute( [NotNull] IRouter next, [NotNull] IEnumerable matchingEntries, - [NotNull] IEnumerable generationEntries) + [NotNull] IEnumerable linkGenerationEntries) { _next = next; @@ -35,9 +35,9 @@ namespace Microsoft.AspNet.Mvc.Routing // a good data-structure here. See #740 _matchingRoutes = matchingEntries.OrderBy(e => e.Precedence).Select(e => e.Route).ToArray(); - // FOR RIGHT NOW - this is just an array of binders. We'll follow up by implementing + // FOR RIGHT NOW - this is just an array of entries. We'll follow up by implementing // a good data-structure here. See #741 - _generationEntries = generationEntries.OrderBy(e => e.Precedence).ToArray(); + _linkGenerationEntries = linkGenerationEntries.OrderBy(e => e.Precedence).ToArray(); } /// @@ -61,7 +61,7 @@ namespace Microsoft.AspNet.Mvc.Routing // and controller. // // Building a proper data structure to optimize this is tracked by #741 - foreach (var entry in _generationEntries) + foreach (var entry in _linkGenerationEntries) { var isMatch = true; foreach (var requiredLinkValue in entry.RequiredLinkValues) @@ -73,23 +73,21 @@ namespace Microsoft.AspNet.Mvc.Routing } } - if (!isMatch) + if (isMatch) { - continue; - } - - var path = GenerateLink(context, entry); - if (path != null) - { - context.IsBound = true; - return path; + var path = GenerateLink(context, entry); + if (path != null) + { + context.IsBound = true; + return path; + } } } return null; } - private string GenerateLink(VirtualPathContext context, AttributeRouteGenerationEntry entry) + private string GenerateLink(VirtualPathContext context, AttributeRouteLinkGenerationEntry entry) { // In attribute the context includes the values that are used to select this entry - typically // these will be the standard 'action', 'controller' and maybe 'area' tokens. However, we don't @@ -135,7 +133,7 @@ namespace Microsoft.AspNet.Mvc.Routing RouteDirection.UrlGeneration); if (!matched) { - // A constrant rejected this link. + // A constraint rejected this link. return null; } diff --git a/src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRouteGenerationEntry.cs b/src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRouteLinkGenerationEntry.cs similarity index 96% rename from src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRouteGenerationEntry.cs rename to src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRouteLinkGenerationEntry.cs index 9c233de5b7..969402cbcb 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRouteGenerationEntry.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRouteLinkGenerationEntry.cs @@ -11,7 +11,7 @@ namespace Microsoft.AspNet.Mvc.Routing /// Used to build an . Represents an individual URL-generating route that will be /// aggregated into the . /// - public class AttributeRouteGenerationEntry + public class AttributeRouteLinkGenerationEntry { /// /// The . diff --git a/src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRouting.cs b/src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRouting.cs index db8cb83f70..ebfd14e84d 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRouting.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Routing/AttributeRouting.cs @@ -31,7 +31,7 @@ namespace Microsoft.AspNet.Mvc.Routing // We're creating one AttributeRouteGenerationEntry per action. This allows us to match the intended // action by expected route values, and then use the TemplateBinder to generate the link. - var generationEntries = new List(); + var generationEntries = new List(); foreach (var routeInfo in routeInfos) { var defaults = routeInfo.ParsedTemplate.Parameters @@ -42,13 +42,13 @@ namespace Microsoft.AspNet.Mvc.Routing .Where(p => p.InlineConstraint != null) .ToDictionary(p => p.Name, p => p.InlineConstraint, StringComparer.OrdinalIgnoreCase); - generationEntries.Add(new AttributeRouteGenerationEntry() + generationEntries.Add(new AttributeRouteLinkGenerationEntry() { Binder = new TemplateBinder(routeInfo.ParsedTemplate, defaults), Defaults = defaults, Constraints = constraints, Precedence = routeInfo.Precedence, - RequiredLinkValues = routeInfo.ActionDescriptor.RouteValues, + RequiredLinkValues = routeInfo.ActionDescriptor.RouteValueDefaults, RouteGroup = routeInfo.RouteGroup, Template = routeInfo.ParsedTemplate, }); @@ -108,7 +108,7 @@ namespace Microsoft.AspNet.Mvc.Routing { var routeInfos = new List(); - foreach (var action in actions.Where(a => a.RouteTemplate != null)) + foreach (var action in actions.Where(a => a.AttributeRouteTemplate != null)) { var constraint = action.RouteConstraints .Where(c => c.RouteKey == AttributeRouting.RouteGroupKey) @@ -121,14 +121,14 @@ namespace Microsoft.AspNet.Mvc.Routing continue; } - var parsedTemplate = TemplateParser.Parse(action.RouteTemplate, constraintResolver); + var parsedTemplate = TemplateParser.Parse(action.AttributeRouteTemplate, constraintResolver); routeInfos.Add(new RouteInfo() { ActionDescriptor = action, ParsedTemplate = parsedTemplate, Precedence = AttributeRoutePrecedence.Compute(parsedTemplate), RouteGroup = constraint.RouteValue, - RouteTemplate = action.RouteTemplate, + RouteTemplate = action.AttributeRouteTemplate, }); } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Routing/AttributeRouteTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Routing/AttributeRouteTests.cs index 612f28327b..fc1f9f5935 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Routing/AttributeRouteTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Routing/AttributeRouteTests.cs @@ -306,11 +306,11 @@ namespace Microsoft.AspNet.Mvc.Routing new RouteValueDictionary(values)); } - private static AttributeRouteGenerationEntry CreateGenerationEntry(string template, object requiredValues) + private static AttributeRouteLinkGenerationEntry CreateGenerationEntry(string template, object requiredValues) { var constraintResolver = CreateConstraintResolver(); - var entry = new AttributeRouteGenerationEntry(); + var entry = new AttributeRouteLinkGenerationEntry(); entry.Template = TemplateParser.Parse(template, constraintResolver); var defaults = entry.Template.Parameters @@ -342,22 +342,22 @@ namespace Microsoft.AspNet.Mvc.Routing return new DefaultInlineConstraintResolver(services, optionsMock.Object); } - private static AttributeRoute CreateAttributeRoute(AttributeRouteGenerationEntry entry) + private static AttributeRoute CreateAttributeRoute(AttributeRouteLinkGenerationEntry entry) { return CreateAttributeRoute(new StubRouter(), entry); } - private static AttributeRoute CreateAttributeRoute(IRouter next, AttributeRouteGenerationEntry entry) + private static AttributeRoute CreateAttributeRoute(IRouter next, AttributeRouteLinkGenerationEntry entry) { return CreateAttributeRoute(next, new[] { entry }); } - private static AttributeRoute CreateAttributeRoute(params AttributeRouteGenerationEntry[] entries) + private static AttributeRoute CreateAttributeRoute(params AttributeRouteLinkGenerationEntry[] entries) { return CreateAttributeRoute(new StubRouter(), entries); } - private static AttributeRoute CreateAttributeRoute(IRouter next, params AttributeRouteGenerationEntry[] entries) + private static AttributeRoute CreateAttributeRoute(IRouter next, params AttributeRouteLinkGenerationEntry[] entries) { return new AttributeRoute( next,