diff --git a/src/Microsoft.AspNetCore.Routing.Abstractions/ILinkGenerator.cs b/src/Microsoft.AspNetCore.Routing.Abstractions/LinkGenerator.cs similarity index 71% rename from src/Microsoft.AspNetCore.Routing.Abstractions/ILinkGenerator.cs rename to src/Microsoft.AspNetCore.Routing.Abstractions/LinkGenerator.cs index 22f8547e9c..c507434429 100644 --- a/src/Microsoft.AspNetCore.Routing.Abstractions/ILinkGenerator.cs +++ b/src/Microsoft.AspNetCore.Routing.Abstractions/LinkGenerator.cs @@ -2,18 +2,21 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; +using Microsoft.AspNetCore.Http; namespace Microsoft.AspNetCore.Routing { - public interface ILinkGenerator + public abstract class LinkGenerator { - bool TryGetLink( + public abstract bool TryGetLink( + HttpContext httpContext, IEnumerable endpoints, RouteValueDictionary explicitValues, RouteValueDictionary ambientValues, out string link); - string GetLink( + public abstract string GetLink( + HttpContext httpContext, IEnumerable endpoints, RouteValueDictionary explicitValues, RouteValueDictionary ambientValues); diff --git a/src/Microsoft.AspNetCore.Routing/DefaultLinkGenerator.cs b/src/Microsoft.AspNetCore.Routing/DefaultLinkGenerator.cs index e5b5f4ea93..d29b05edcd 100644 --- a/src/Microsoft.AspNetCore.Routing/DefaultLinkGenerator.cs +++ b/src/Microsoft.AspNetCore.Routing/DefaultLinkGenerator.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text.Encodings.Web; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing.Internal; using Microsoft.AspNetCore.Routing.Matchers; using Microsoft.AspNetCore.Routing.Template; @@ -13,7 +14,7 @@ using Microsoft.Extensions.ObjectPool; namespace Microsoft.AspNetCore.Routing { - internal class DefaultLinkGenerator : ILinkGenerator + internal class DefaultLinkGenerator : LinkGenerator { private readonly MatchProcessorFactory _matchProcessorFactory; private readonly ObjectPool _uriBuildingContextPool; @@ -29,12 +30,13 @@ namespace Microsoft.AspNetCore.Routing _logger = logger; } - public string GetLink( + public override string GetLink( + HttpContext httpContext, IEnumerable endpoints, RouteValueDictionary explicitValues, RouteValueDictionary ambientValues) { - if (TryGetLink(endpoints, explicitValues, ambientValues, out var link)) + if (TryGetLink(httpContext, endpoints, explicitValues, ambientValues, out var link)) { return link; } @@ -42,7 +44,8 @@ namespace Microsoft.AspNetCore.Routing throw new InvalidOperationException("Could not find a matching endpoint to generate a link."); } - public bool TryGetLink( + public override bool TryGetLink( + HttpContext httpContext, IEnumerable endpoints, RouteValueDictionary explicitValues, RouteValueDictionary ambientValues, @@ -64,7 +67,7 @@ namespace Microsoft.AspNetCore.Routing foreach (var endpoint in matcherEndpoints) { - link = GetLink(endpoint, explicitValues, ambientValues); + link = GetLink(httpContext, endpoint, explicitValues, ambientValues); if (link != null) { return true; @@ -75,6 +78,7 @@ namespace Microsoft.AspNetCore.Routing } private string GetLink( + HttpContext httpContext, MatcherEndpoint endpoint, RouteValueDictionary explicitValues, RouteValueDictionary ambientValues) @@ -92,7 +96,7 @@ namespace Microsoft.AspNetCore.Routing return null; } - if (!Match(endpoint, templateValuesResult.CombinedValues)) + if (!Match(httpContext, endpoint, templateValuesResult.CombinedValues)) { return null; } @@ -100,7 +104,7 @@ namespace Microsoft.AspNetCore.Routing return templateBinder.BindValues(templateValuesResult.AcceptedValues); } - private bool Match(MatcherEndpoint endpoint, RouteValueDictionary routeValues) + private bool Match(HttpContext httpContext, MatcherEndpoint endpoint, RouteValueDictionary routeValues) { if (routeValues == null) { @@ -117,7 +121,7 @@ namespace Microsoft.AspNetCore.Routing } var matchProcessor = _matchProcessorFactory.Create(matchProcessorReference); - if (!matchProcessor.ProcessOutbound(httpContext: null, routeValues)) + if (!matchProcessor.ProcessOutbound(httpContext, routeValues)) { return false; } diff --git a/src/Microsoft.AspNetCore.Routing/DependencyInjection/DispatcherServiceCollectionExtensions.cs b/src/Microsoft.AspNetCore.Routing/DependencyInjection/DispatcherServiceCollectionExtensions.cs index afd9a4a4b0..b17150e784 100644 --- a/src/Microsoft.AspNetCore.Routing/DependencyInjection/DispatcherServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNetCore.Routing/DependencyInjection/DispatcherServiceCollectionExtensions.cs @@ -41,7 +41,7 @@ namespace Microsoft.Extensions.DependencyInjection // Link generation related services services.TryAddSingleton, NameBasedEndpointFinder>(); services.TryAddSingleton, RouteValuesBasedEndpointFinder>(); - services.TryAddSingleton(); + services.TryAddSingleton(); // // Endpoint Selection // diff --git a/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGeneratorTest.cs b/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGeneratorTest.cs index d73352a9c5..4416256954 100644 --- a/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGeneratorTest.cs +++ b/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGeneratorTest.cs @@ -7,7 +7,6 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Routing.EndpointFinders; using Microsoft.AspNetCore.Routing.Internal; using Microsoft.AspNetCore.Routing.Matchers; -using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.ObjectPool; using Microsoft.Extensions.Options; @@ -27,7 +26,11 @@ namespace Microsoft.AspNetCore.Routing var context = CreateRouteValuesContext(new { controller = "Home" }); // Act - var link = linkGenerator.GetLink(new[] { endpoint }, context.ExplicitValues, context.AmbientValues); + var link = linkGenerator.GetLink( + httpContext: null, + new[] { endpoint }, + context.ExplicitValues, + context.AmbientValues); // Assert Assert.Equal("/Home", link); @@ -44,7 +47,11 @@ namespace Microsoft.AspNetCore.Routing // Act & Assert var exception = Assert.Throws( - () => linkGenerator.GetLink(new[] { endpoint }, context.ExplicitValues, context.AmbientValues)); + () => linkGenerator.GetLink( + httpContext: null, + new[] { endpoint }, + context.ExplicitValues, + context.AmbientValues)); Assert.Equal(expectedMessage, exception.Message); } @@ -58,6 +65,7 @@ namespace Microsoft.AspNetCore.Routing // Act var canGenerateLink = linkGenerator.TryGetLink( + httpContext: null, new[] { endpoint }, context.ExplicitValues, context.AmbientValues, @@ -80,6 +88,7 @@ namespace Microsoft.AspNetCore.Routing // Act var link = linkGenerator.GetLink( + httpContext: null, new[] { endpoint1, endpoint2, endpoint3 }, context.ExplicitValues, context.AmbientValues); @@ -100,6 +109,7 @@ namespace Microsoft.AspNetCore.Routing // Act var link = linkGenerator.GetLink( + httpContext: null, new[] { endpoint1, endpoint2, endpoint3 }, context.ExplicitValues, context.AmbientValues); @@ -119,7 +129,11 @@ namespace Microsoft.AspNetCore.Routing ambientValues: new { controller = "Home", action = "Index" }); // Act - var link = linkGenerator.GetLink(new[] { endpoint }, context.ExplicitValues, context.AmbientValues); + var link = linkGenerator.GetLink( + httpContext: null, + new[] { endpoint }, + context.ExplicitValues, + context.AmbientValues); // Assert Assert.Equal("/Home/Index?name=name%20with%20%25special%20%23characters", link); @@ -136,7 +150,11 @@ namespace Microsoft.AspNetCore.Routing new { controller = "Home", action = "Index" }); // Act - var link = linkGenerator.GetLink(new[] { endpoint }, context.ExplicitValues, context.AmbientValues); + var link = linkGenerator.GetLink( + httpContext: null, + new[] { endpoint }, + context.ExplicitValues, + context.AmbientValues); // Assert Assert.Equal("/Home/Index?color=red&color=green&color=blue", link); @@ -153,7 +171,11 @@ namespace Microsoft.AspNetCore.Routing new { controller = "Home", action = "Index" }); // Act - var link = linkGenerator.GetLink(new[] { endpoint }, context.ExplicitValues, context.AmbientValues); + var link = linkGenerator.GetLink( + httpContext: null, + new[] { endpoint }, + context.ExplicitValues, + context.AmbientValues); // Assert Assert.Equal("/Home/Index?items=10&items=20&items=30", link); @@ -170,7 +192,11 @@ namespace Microsoft.AspNetCore.Routing new { controller = "Home", action = "Index" }); // Act - var link = linkGenerator.GetLink(new[] { endpoint }, context.ExplicitValues, context.AmbientValues); + var link = linkGenerator.GetLink( + httpContext: null, + new[] { endpoint }, + context.ExplicitValues, + context.AmbientValues); // Assert Assert.Equal("/Home/Index", link); @@ -187,7 +213,11 @@ namespace Microsoft.AspNetCore.Routing new { controller = "Home", action = "Index" }); // Act - var link = linkGenerator.GetLink(new[] { endpoint }, context.ExplicitValues, context.AmbientValues); + var link = linkGenerator.GetLink( + httpContext: null, + new[] { endpoint }, + context.ExplicitValues, + context.AmbientValues); // Assert Assert.Equal("/Home/Index?page=1&color=red&color=green&color=blue&message=textfortest", link); @@ -204,7 +234,11 @@ namespace Microsoft.AspNetCore.Routing ambientValues: new { controller = "Home" }); // Act - var link = linkGenerator.GetLink(new[] { endpoint }, context.ExplicitValues, context.AmbientValues); + var link = linkGenerator.GetLink( + httpContext: null, + new[] { endpoint }, + context.ExplicitValues, + context.AmbientValues); // Assert Assert.Equal("/Home/Index", link); @@ -582,7 +616,11 @@ namespace Microsoft.AspNetCore.Routing suppliedValues: new { action = "Index", controller = "Home", name = "products" }); // Act - var link = linkGenerator.GetLink(new[] { endpoint }, context.ExplicitValues, context.AmbientValues); + var link = linkGenerator.GetLink( + httpContext: null, + new[] { endpoint }, + context.ExplicitValues, + context.AmbientValues); // Assert Assert.Equal("/Home/Index/products", link); @@ -598,7 +636,11 @@ namespace Microsoft.AspNetCore.Routing suppliedValues: new { action = "Index", controller = "Home" }); // Act - var link = linkGenerator.GetLink(new[] { endpoint }, context.ExplicitValues, context.AmbientValues); + var link = linkGenerator.GetLink( + httpContext: null, + new[] { endpoint }, + context.ExplicitValues, + context.AmbientValues); // Assert Assert.Equal("/Home/Index", link); @@ -616,7 +658,11 @@ namespace Microsoft.AspNetCore.Routing suppliedValues: new { action = "Index", controller = "Home", name = "products" }); // Act - var link = linkGenerator.GetLink(new[] { endpoint }, context.ExplicitValues, context.AmbientValues); + var link = linkGenerator.GetLink( + httpContext: null, + new[] { endpoint }, + context.ExplicitValues, + context.AmbientValues); // Assert Assert.Equal("/Home/Index/products", link); @@ -634,7 +680,11 @@ namespace Microsoft.AspNetCore.Routing suppliedValues: new { action = "Index", controller = "Home" }); // Act - var link = linkGenerator.GetLink(new[] { endpoint }, context.ExplicitValues, context.AmbientValues); + var link = linkGenerator.GetLink( + httpContext: null, + new[] { endpoint }, + context.ExplicitValues, + context.AmbientValues); // Assert Assert.Equal("/Home/Index", link); @@ -650,7 +700,11 @@ namespace Microsoft.AspNetCore.Routing suppliedValues: new { action = "Index", controller = "Home", name = "products", format = "json" }); // Act - var link = linkGenerator.GetLink(new[] { endpoint }, context.ExplicitValues, context.AmbientValues); + var link = linkGenerator.GetLink( + httpContext: null, + new[] { endpoint }, + context.ExplicitValues, + context.AmbientValues); // Assert Assert.Equal("/Home/Index/products?format=json", link); @@ -710,7 +764,11 @@ namespace Microsoft.AspNetCore.Routing suppliedValues: new { action = "Index", controller = "Home" }); // Act - var link = linkGenerator.GetLink(new[] { endpoint }, context.ExplicitValues, context.AmbientValues); + var link = linkGenerator.GetLink( + httpContext: null, + new[] { endpoint }, + context.ExplicitValues, + context.AmbientValues); // Assert Assert.Equal("/Home/Index", link); @@ -796,7 +854,7 @@ namespace Microsoft.AspNetCore.Routing null); } - private ILinkGenerator CreateLinkGenerator() + private LinkGenerator CreateLinkGenerator() { return new DefaultLinkGenerator( new DefaultMatchProcessorFactory(