diff --git a/build/dependencies.props b/build/dependencies.props index e0d8d9f5dc..12ae16b6a4 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -5,36 +5,36 @@ 0.10.13 3.0.0-alpha1-20181011.3 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 + 3.0.0-alpha1-10645 2.0.9 2.1.3 - 2.2.0-preview2-26905-02 + 2.2.0-preview3-27014-02 15.6.1 4.10.0 2.0.3 diff --git a/src/Microsoft.AspNetCore.Routing/Internal/LinkGenerationDecisionTree.cs b/src/Microsoft.AspNetCore.Routing/Internal/LinkGenerationDecisionTree.cs index 6242198a46..f276bf0658 100644 --- a/src/Microsoft.AspNetCore.Routing/Internal/LinkGenerationDecisionTree.cs +++ b/src/Microsoft.AspNetCore.Routing/Internal/LinkGenerationDecisionTree.cs @@ -164,9 +164,10 @@ namespace Microsoft.AspNetCore.Routing.Internal return x.IsFallbackMatch.CompareTo(y.IsFallbackMatch); } - return StringComparer.Ordinal.Compare( + return string.Compare( x.Match.Entry.RouteTemplate.TemplateText, - y.Match.Entry.RouteTemplate.TemplateText); + y.Match.Entry.RouteTemplate.TemplateText, + StringComparison.Ordinal); } } diff --git a/src/Microsoft.AspNetCore.Routing/Matching/HttpMethodMatcherPolicy.cs b/src/Microsoft.AspNetCore.Routing/Matching/HttpMethodMatcherPolicy.cs index b03c307a21..f1ec26d67d 100644 --- a/src/Microsoft.AspNetCore.Routing/Matching/HttpMethodMatcherPolicy.cs +++ b/src/Microsoft.AspNetCore.Routing/Matching/HttpMethodMatcherPolicy.cs @@ -285,7 +285,7 @@ namespace Microsoft.AspNetCore.Routing.Matching { for (var i = 0; i < httpMethods.Count; i++) { - if (StringComparer.OrdinalIgnoreCase.Equals(httpMethods[i], httpMethod)) + if (string.Equals(httpMethods[i], httpMethod, StringComparison.OrdinalIgnoreCase)) { return true; } diff --git a/src/Microsoft.AspNetCore.Routing/Template/TemplateBinder.cs b/src/Microsoft.AspNetCore.Routing/Template/TemplateBinder.cs index 40755676fc..4236c3c012 100644 --- a/src/Microsoft.AspNetCore.Routing/Template/TemplateBinder.cs +++ b/src/Microsoft.AspNetCore.Routing/Template/TemplateBinder.cs @@ -471,11 +471,7 @@ namespace Microsoft.AspNetCore.Routing.Template else if (part is RoutePatternParameterPart parameterPart) { // If it's a parameter, get its value - var hasValue = acceptedValues.TryGetValue(parameterPart.Name, out var value); - if (hasValue) - { - acceptedValues.Remove(parameterPart.Name); - } + acceptedValues.Remove(parameterPart.Name, out var value); var isSameAsDefault = false; if (_defaults != null && diff --git a/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGeneratorTest.cs b/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGeneratorTest.cs index 831576c41c..1f76ef3045 100644 --- a/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGeneratorTest.cs +++ b/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGeneratorTest.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Routing.TestObjects; using Microsoft.Extensions.DependencyInjection; using Xunit; @@ -597,6 +598,64 @@ namespace Microsoft.AspNetCore.Routing Assert.NotSame(original, actual); } + [Fact] + public void GetPathByRouteValues_UsesFirstTemplateThatSucceeds() + { + // Arrange + var endpointControllerAction = EndpointFactory.CreateRouteEndpoint( + "Home/Index", + order: 3, + defaults: new { controller = "Home", action = "Index", }, + metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) }); + var endpointController = EndpointFactory.CreateRouteEndpoint( + "Home", + order: 2, + defaults: new { controller = "Home", action = "Index", }, + metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) }); + var endpointEmpty = EndpointFactory.CreateRouteEndpoint( + "", + order: 1, + defaults: new { controller = "Home", action = "Index", }, + metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) }); + + // This endpoint should be used to generate the link when an id is present + var endpointControllerActionParameter = EndpointFactory.CreateRouteEndpoint( + "Home/Index/{id}", + order: 0, + defaults: new { controller = "Home", action = "Index", }, + metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) }); + + var linkGenerator = CreateLinkGenerator(endpointControllerAction, endpointController, endpointEmpty, endpointControllerActionParameter); + + var context = new EndpointSelectorContext() + { + RouteValues = new RouteValueDictionary(new { controller = "Home", action = "Index", }) + }; + var httpContext = CreateHttpContext(); + httpContext.Features.Set(context); + + // Act + var pathWithoutId = linkGenerator.GetPathByRouteValues( + httpContext, + routeName: null, + values: new RouteValueDictionary()); + + var pathWithId = linkGenerator.GetPathByRouteValues( + httpContext, + routeName: null, + values: new RouteValueDictionary(new { id = "3" })); + + var pathWithCustom = linkGenerator.GetPathByRouteValues( + httpContext, + routeName: null, + values: new RouteValueDictionary(new { custom = "Custom" })); + + // Assert + Assert.Equal("/", pathWithoutId); + Assert.Equal("/Home/Index/3", pathWithId); + Assert.Equal("/?custom=Custom", pathWithCustom); + } + protected override void AddAdditionalServices(IServiceCollection services) { services.AddSingleton, IntAddressScheme>();