From 3ba6f3549576fc411df28d1547feff46bbec4533 Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Thu, 19 Jul 2018 22:03:39 -0700 Subject: [PATCH] React to RoutePattern changes in Routing --- .../Internal/MvcEndpointDataSource.cs | 13 ++--- .../ConsumesAttributeTests.cs | 6 +- .../Internal/MvcEndpointDataSourceTests.cs | 58 ++++++++++--------- .../Routing/DispatcherUrlHelperTest.cs | 29 +++++----- 4 files changed, 52 insertions(+), 54 deletions(-) diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcEndpointDataSource.cs b/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcEndpointDataSource.cs index a76dbe8c93..c8738bb20e 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcEndpointDataSource.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcEndpointDataSource.cs @@ -12,6 +12,7 @@ using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.EndpointConstraints; using Microsoft.AspNetCore.Routing.Matchers; +using Microsoft.AspNetCore.Routing.Patterns; using Microsoft.AspNetCore.Routing.Template; using Microsoft.Extensions.Primitives; @@ -298,20 +299,18 @@ namespace Microsoft.AspNetCore.Mvc.Internal return invoker.InvokeAsync(); }; + var defaults = new RouteValueDictionary(nonInlineDefaults); + EnsureRequiredValuesInDefaults(action.RouteValues, defaults); + var metadataCollection = BuildEndpointMetadata(action, routeName, source); var endpoint = new MatcherEndpoint( next => invokerDelegate, - template, - new RouteValueDictionary(nonInlineDefaults), + RoutePatternFactory.Parse(template, defaults, constraints: null), new RouteValueDictionary(action.RouteValues), order, metadataCollection, action.DisplayName); - // Use defaults after the endpoint is created as it merges both the inline and - // non-inline defaults into one. - EnsureRequiredValuesInDefaults(endpoint.RequiredValues, endpoint.Defaults); - return endpoint; } @@ -373,7 +372,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal // Required values: controller=foo, action=bar // Final constructed template: foo/bar/{category}/{id?} // Final defaults: controller=foo, action=bar, category=products - private void EnsureRequiredValuesInDefaults(RouteValueDictionary requiredValues, RouteValueDictionary defaults) + private void EnsureRequiredValuesInDefaults(IDictionary requiredValues, RouteValueDictionary defaults) { foreach (var kvp in requiredValues) { diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ConsumesAttributeTests.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ConsumesAttributeTests.cs index 83bae7b4b0..30514d5ac8 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ConsumesAttributeTests.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ConsumesAttributeTests.cs @@ -14,6 +14,7 @@ using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.EndpointConstraints; using Microsoft.AspNetCore.Routing.Matchers; +using Microsoft.AspNetCore.Routing.Patterns; using Microsoft.Net.Http.Headers; using Moq; using Xunit; @@ -297,12 +298,11 @@ namespace Microsoft.AspNetCore.Mvc private MatcherEndpoint CreateEndpoint(params IEndpointConstraint[] constraints) { - EndpointMetadataCollection endpointMetadata = new EndpointMetadataCollection(constraints); + var endpointMetadata = new EndpointMetadataCollection(constraints); return new MatcherEndpoint( (r) => null, - "", - new RouteValueDictionary(), + RoutePatternFactory.Parse("/"), new RouteValueDictionary(), 0, endpointMetadata, diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/MvcEndpointDataSourceTests.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/MvcEndpointDataSourceTests.cs index 983af123c6..fb0df12fd3 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/MvcEndpointDataSourceTests.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/MvcEndpointDataSourceTests.cs @@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal Assert.Equal(displayName, matcherEndpoint.DisplayName); Assert.Equal(order, matcherEndpoint.Order); - Assert.Equal(template, matcherEndpoint.Template); + Assert.Equal(template, matcherEndpoint.RoutePattern.RawText); } [Fact] @@ -197,7 +197,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal // Assert var inspectors = finalEndpointTemplates - .Select(t => new Action(e => Assert.Equal(t, Assert.IsType(e).Template))) + .Select(t => new Action(e => Assert.Equal(t, Assert.IsType(e).RoutePattern.RawText))) .ToArray(); // Assert @@ -224,7 +224,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal // Assert var inspectors = finalEndpointTemplates - .Select(t => new Action(e => Assert.Equal(t, Assert.IsType(e).Template))) + .Select(t => new Action(e => Assert.Equal(t, Assert.IsType(e).RoutePattern.RawText))) .ToArray(); // Assert @@ -248,8 +248,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal // Assert Assert.Collection(endpoints, - (e) => Assert.Equal("TestController", Assert.IsType(e).Template), - (e) => Assert.Equal("TestController/TestAction", Assert.IsType(e).Template)); + (e) => Assert.Equal("TestController", Assert.IsType(e).RoutePattern.RawText), + (e) => Assert.Equal("TestController/TestAction", Assert.IsType(e).RoutePattern.RawText)); } [Fact] @@ -276,8 +276,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal // Assert Assert.Collection(endpoints1, - (e) => Assert.Equal("TestController", Assert.IsType(e).Template), - (e) => Assert.Equal("TestController/TestAction", Assert.IsType(e).Template)); + (e) => Assert.Equal("TestController", Assert.IsType(e).RoutePattern.RawText), + (e) => Assert.Equal("TestController/TestAction", Assert.IsType(e).RoutePattern.RawText)); Assert.Same(endpoints1, endpoints2); actionDescriptorCollectionProviderMock.VerifyGet(m => m.ActionDescriptors, Times.Once); @@ -318,8 +318,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal var endpoints = dataSource.Endpoints; Assert.Collection(endpoints, - (e) => Assert.Equal("TestController", Assert.IsType(e).Template), - (e) => Assert.Equal("TestController/TestAction", Assert.IsType(e).Template)); + (e) => Assert.Equal("TestController", Assert.IsType(e).RoutePattern.RawText), + (e) => Assert.Equal("TestController/TestAction", Assert.IsType(e).RoutePattern.RawText)); actionDescriptorCollectionProviderMock .Setup(m => m.ActionDescriptors) @@ -335,7 +335,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal Assert.NotSame(endpoints, newEndpoints); Assert.Collection(newEndpoints, - (e) => Assert.Equal("NewTestController/NewTestAction", Assert.IsType(e).Template)); + (e) => Assert.Equal("NewTestController/NewTestAction", Assert.IsType(e).RoutePattern.RawText)); } [Fact] @@ -357,8 +357,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal // Assert Assert.Collection(endpoints, - (e) => Assert.Equal("TestController/TestAction1", Assert.IsType(e).Template), - (e) => Assert.Equal("TestController/TestAction2", Assert.IsType(e).Template)); + (e) => Assert.Equal("TestController/TestAction1", Assert.IsType(e).RoutePattern.RawText), + (e) => Assert.Equal("TestController/TestAction2", Assert.IsType(e).RoutePattern.RawText)); } [Theory] @@ -381,7 +381,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal var endpoints = dataSource.Endpoints; var inspectors = finalEndpointTemplates - .Select(t => new Action(e => Assert.Equal(t, Assert.IsType(e).Template))) + .Select(t => new Action(e => Assert.Equal(t, Assert.IsType(e).RoutePattern.RawText))) .ToArray(); // Assert @@ -431,7 +431,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal var routeNameMetadata = matcherEndpoint.Metadata.GetMetadata(); Assert.NotNull(routeNameMetadata); Assert.Equal("namedRoute", routeNameMetadata.Name); - Assert.Equal("named/Home/Index/{id?}", matcherEndpoint.Template); + Assert.Equal("named/Home/Index/{id?}", matcherEndpoint.RoutePattern.RawText); }, (ep) => { @@ -439,7 +439,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal var routeNameMetadata = matcherEndpoint.Metadata.GetMetadata(); Assert.NotNull(routeNameMetadata); Assert.Equal("namedRoute", routeNameMetadata.Name); - Assert.Equal("named/Products/Details/{id?}", matcherEndpoint.Template); + Assert.Equal("named/Products/Details/{id?}", matcherEndpoint.RoutePattern.RawText); }); } @@ -467,25 +467,25 @@ namespace Microsoft.AspNetCore.Mvc.Internal (ep) => { var matcherEndpoint = Assert.IsType(ep); - Assert.Equal("Home/Index/{id?}", matcherEndpoint.Template); + Assert.Equal("Home/Index/{id?}", matcherEndpoint.RoutePattern.RawText); Assert.Equal(1, matcherEndpoint.Order); }, (ep) => { var matcherEndpoint = Assert.IsType(ep); - Assert.Equal("named/Home/Index/{id?}", matcherEndpoint.Template); + Assert.Equal("named/Home/Index/{id?}", matcherEndpoint.RoutePattern.RawText); Assert.Equal(2, matcherEndpoint.Order); }, (ep) => { var matcherEndpoint = Assert.IsType(ep); - Assert.Equal("Products/Details/{id?}", matcherEndpoint.Template); + Assert.Equal("Products/Details/{id?}", matcherEndpoint.RoutePattern.RawText); Assert.Equal(1, matcherEndpoint.Order); }, (ep) => { var matcherEndpoint = Assert.IsType(ep); - Assert.Equal("named/Products/Details/{id?}", matcherEndpoint.Template); + Assert.Equal("named/Products/Details/{id?}", matcherEndpoint.RoutePattern.RawText); Assert.Equal(2, matcherEndpoint.Order); }); } @@ -587,8 +587,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal // Assert var endpoint = Assert.Single(endpoints); var matcherEndpoint = Assert.IsType(endpoint); - Assert.Equal("Foo/Bar", matcherEndpoint.Template); - AssertIsSubset(expectedDefaults, matcherEndpoint.Defaults); + Assert.Equal("Foo/Bar", matcherEndpoint.RoutePattern.RawText); + AssertIsSubset(expectedDefaults, matcherEndpoint.RoutePattern.Defaults); } [Fact] @@ -609,8 +609,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal // Assert var endpoint = Assert.Single(endpoints); var matcherEndpoint = Assert.IsType(endpoint); - Assert.Equal("Foo/Bar", matcherEndpoint.Template); - AssertIsSubset(expectedDefaults, matcherEndpoint.Defaults); + Assert.Equal("Foo/Bar", matcherEndpoint.RoutePattern.RawText); + AssertIsSubset(expectedDefaults, matcherEndpoint.RoutePattern.Defaults); } [Fact] @@ -632,8 +632,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal // Assert var endpoint = Assert.Single(endpoints); var matcherEndpoint = Assert.IsType(endpoint); - Assert.Equal("Foo/Bar/{subscription=general}", matcherEndpoint.Template); - AssertIsSubset(expectedDefaults, matcherEndpoint.Defaults); + Assert.Equal("Foo/Bar/{subscription=general}", matcherEndpoint.RoutePattern.RawText); + AssertIsSubset(expectedDefaults, matcherEndpoint.RoutePattern.Defaults); } [Fact] @@ -654,8 +654,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal // Assert var endpoint = Assert.Single(endpoints); var matcherEndpoint = Assert.IsType(endpoint); - Assert.Equal("Foo/Bar", matcherEndpoint.Template); - AssertIsSubset(expectedDefaults, matcherEndpoint.Defaults); + Assert.Equal("Foo/Bar", matcherEndpoint.RoutePattern.RawText); + AssertIsSubset(expectedDefaults, matcherEndpoint.RoutePattern.Defaults); } private MvcEndpointDataSource CreateMvcEndpointDataSource( @@ -729,7 +729,9 @@ namespace Microsoft.AspNetCore.Mvc.Internal return actionDescriptor; } - private void AssertIsSubset(RouteValueDictionary subset, RouteValueDictionary fullSet) + private void AssertIsSubset( + IReadOnlyDictionary subset, + IReadOnlyDictionary fullSet) { foreach (var subsetPair in subset) { diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/DispatcherUrlHelperTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/DispatcherUrlHelperTest.cs index 5d52f760a7..b069feabc6 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/DispatcherUrlHelperTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/DispatcherUrlHelperTest.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Matchers; +using Microsoft.AspNetCore.Routing.Patterns; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Xunit; @@ -35,8 +36,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing var endpoints = GetDefaultEndpoints(); endpoints.Add(new MatcherEndpoint( next => httpContext => Task.CompletedTask, - template, - new RouteValueDictionary(), + RoutePatternFactory.Parse(template), new RouteValueDictionary(), 0, EndpointMetadataCollection.Empty, @@ -51,8 +51,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing { Endpoint = new MatcherEndpoint( next => cntxt => Task.CompletedTask, - "/", - new RouteValueDictionary(), + RoutePatternFactory.Parse("/"), new RouteValueDictionary(), 0, EndpointMetadataCollection.Empty, @@ -100,14 +99,14 @@ namespace Microsoft.AspNetCore.Mvc.Routing private List GetDefaultEndpoints() { var endpoints = new List(); - endpoints.Add(CreateEndpoint(null, "home/newaction/{id?}", new { id = "defaultid", controller = "home", action = "newaction" }, 1)); - endpoints.Add(CreateEndpoint(null, "home/contact/{id?}", new { id = "defaultid", controller = "home", action = "contact" }, 2)); - endpoints.Add(CreateEndpoint(null, "home2/newaction/{id?}", new { id = "defaultid", controller = "home2", action = "newaction" }, 3)); - endpoints.Add(CreateEndpoint(null, "home2/contact/{id?}", new { id = "defaultid", controller = "home2", action = "contact" }, 4)); - endpoints.Add(CreateEndpoint(null, "home3/contact/{id?}", new { id = "defaultid", controller = "home3", action = "contact" }, 5)); - endpoints.Add(CreateEndpoint("namedroute", "named/home/newaction/{id?}", new { id = "defaultid", controller = "home", action = "newaction" }, 6)); - endpoints.Add(CreateEndpoint("namedroute", "named/home2/newaction/{id?}", new { id = "defaultid", controller = "home2", action = "newaction" }, 7)); - endpoints.Add(CreateEndpoint("namedroute", "named/home/contact/{id?}", new { id = "defaultid", controller = "home", action = "contact" }, 8)); + endpoints.Add(CreateEndpoint(null, "home/newaction/{id}", new { id = "defaultid", controller = "home", action = "newaction" }, 1)); + endpoints.Add(CreateEndpoint(null, "home/contact/{id}", new { id = "defaultid", controller = "home", action = "contact" }, 2)); + endpoints.Add(CreateEndpoint(null, "home2/newaction/{id}", new { id = "defaultid", controller = "home2", action = "newaction" }, 3)); + endpoints.Add(CreateEndpoint(null, "home2/contact/{id}", new { id = "defaultid", controller = "home2", action = "contact" }, 4)); + endpoints.Add(CreateEndpoint(null, "home3/contact/{id}", new { id = "defaultid", controller = "home3", action = "contact" }, 5)); + endpoints.Add(CreateEndpoint("namedroute", "named/home/newaction/{id}", new { id = "defaultid", controller = "home", action = "newaction" }, 6)); + endpoints.Add(CreateEndpoint("namedroute", "named/home2/newaction/{id}", new { id = "defaultid", controller = "home2", action = "newaction" }, 7)); + endpoints.Add(CreateEndpoint("namedroute", "named/home/contact/{id}", new { id = "defaultid", controller = "home", action = "contact" }, 8)); endpoints.Add(CreateEndpoint("MyRouteName", "any/url", new { }, 9)); return endpoints; } @@ -122,8 +121,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing return new MatcherEndpoint( next => (httpContext) => Task.CompletedTask, - template, - new RouteValueDictionary(defaults), + RoutePatternFactory.Parse(template, defaults, constraints: null), new RouteValueDictionary(), order, metadata, @@ -149,8 +147,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing { return new MatcherEndpoint( next => c => Task.CompletedTask, - template, - defaults, + RoutePatternFactory.Parse(template, defaults, constraints: null), new RouteValueDictionary(), 0, EndpointMetadataCollection.Empty,