diff --git a/build/dependencies.props b/build/dependencies.props
index 6697d0589f..3015d4e3c2 100644
--- a/build/dependencies.props
+++ b/build/dependencies.props
@@ -39,7 +39,7 @@
2.2.0-preview1-34869
2.2.0-preview1-34869
2.2.0-preview1-34869
- 2.2.0-preview1-34869
+ 2.2.0-a-preview1-routing-lg-16736
2.2.0-preview1-34869
2.2.0-preview1-34869
2.2.0-preview1-34869
@@ -48,8 +48,8 @@
2.2.0-preview1-34869
2.2.0-preview1-34869
2.2.0-preview1-34869
- 2.2.0-preview1-34869
- 2.2.0-preview1-34869
+ 2.2.0-a-preview1-change-linkgenerator-api-16845
+ 2.2.0-a-preview1-change-linkgenerator-api-16845
2.2.0-preview1-34869
2.2.0-preview1-34869
2.2.0-preview1-34869
diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Internal/ControllerActionDescriptorBuilder.cs b/src/Microsoft.AspNetCore.Mvc.Core/Internal/ControllerActionDescriptorBuilder.cs
index f24859eb20..27a548c37a 100644
--- a/src/Microsoft.AspNetCore.Mvc.Core/Internal/ControllerActionDescriptorBuilder.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Core/Internal/ControllerActionDescriptorBuilder.cs
@@ -12,7 +12,6 @@ using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Routing;
-using Microsoft.AspNetCore.Routing.Metadata;
using Resources = Microsoft.AspNetCore.Mvc.Core.Resources;
namespace Microsoft.AspNetCore.Mvc.Internal
diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Internal/DefaultApplicationModelProvider.cs b/src/Microsoft.AspNetCore.Mvc.Core/Internal/DefaultApplicationModelProvider.cs
index 00ad6bf594..c79b2b209d 100644
--- a/src/Microsoft.AspNetCore.Mvc.Core/Internal/DefaultApplicationModelProvider.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Core/Internal/DefaultApplicationModelProvider.cs
@@ -11,7 +11,7 @@ using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Routing;
-using Microsoft.AspNetCore.Routing.Metadata;
+using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Internal;
using Microsoft.Extensions.Options;
diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcEndpointDataSource.cs b/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcEndpointDataSource.cs
index 3770856e64..9e4ff9b92c 100644
--- a/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcEndpointDataSource.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcEndpointDataSource.cs
@@ -3,17 +3,14 @@
using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Abstractions;
-using Microsoft.AspNetCore.Mvc.ActionConstraints;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Routing.Matching;
-using Microsoft.AspNetCore.Routing.Metadata;
using Microsoft.AspNetCore.Routing.Patterns;
using Microsoft.AspNetCore.Routing.Template;
using Microsoft.Extensions.Primitives;
@@ -295,11 +292,16 @@ namespace Microsoft.AspNetCore.Mvc.Internal
var defaults = new RouteValueDictionary(nonInlineDefaults);
EnsureRequiredValuesInDefaults(action.RouteValues, defaults);
- var metadataCollection = BuildEndpointMetadata(action, routeName, source, suppressLinkGeneration);
+ var metadataCollection = BuildEndpointMetadata(
+ action,
+ routeName,
+ new RouteValueDictionary(action.RouteValues),
+ source,
+ suppressLinkGeneration);
+
var endpoint = new MatcherEndpoint(
next => invokerDelegate,
RoutePatternFactory.Parse(template, defaults, constraints: null),
- new RouteValueDictionary(action.RouteValues),
order,
metadataCollection,
action.DisplayName);
@@ -310,6 +312,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
private static EndpointMetadataCollection BuildEndpointMetadata(
ActionDescriptor action,
string routeName,
+ RouteValueDictionary requiredValues,
object source,
bool suppressLinkGeneration)
{
@@ -323,10 +326,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
metadata.AddRange(action.EndpointMetadata);
}
- if (!string.IsNullOrEmpty(routeName))
- {
- metadata.Add(new RouteNameMetadata(routeName));
- }
+ metadata.Add(new RouteValuesAddressMetadata(routeName, requiredValues));
// Add filter descriptors to endpoint metadata
if (action.FilterDescriptors != null && action.FilterDescriptors.Count > 0)
@@ -349,7 +349,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
{
metadata.Add(new HttpMethodMetadata(httpMethodActionConstraint.HttpMethods));
}
- else if (actionConstraint is ConsumesAttribute consumesAttribute &&
+ else if (actionConstraint is ConsumesAttribute consumesAttribute &&
!metadata.OfType().Any())
{
metadata.Add(new ConsumesMetadata(consumesAttribute.ContentTypes.ToArray()));
@@ -444,16 +444,6 @@ namespace Microsoft.AspNetCore.Mvc.Internal
public List ConventionalEndpointInfos { get; }
- private class RouteNameMetadata : IRouteNameMetadata
- {
- public RouteNameMetadata(string routeName)
- {
- Name = routeName;
- }
-
- public string Name { get; }
- }
-
private class SuppressLinkGenerationMetadata : ISuppressLinkGenerationMetadata { }
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Routing/ConsumesMatcherPolicy.cs b/src/Microsoft.AspNetCore.Mvc.Core/Routing/ConsumesMatcherPolicy.cs
index dcaeaca936..3adacf3c38 100644
--- a/src/Microsoft.AspNetCore.Mvc.Core/Routing/ConsumesMatcherPolicy.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Core/Routing/ConsumesMatcherPolicy.cs
@@ -142,7 +142,6 @@ namespace Microsoft.AspNetCore.Mvc.Routing
return Task.CompletedTask;
},
RoutePatternFactory.Parse("/"),
- new RouteValueDictionary(),
0,
EndpointMetadataCollection.Empty,
Http415EndpointDisplayName);
diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Routing/EndpointRoutingUrlHelper.cs b/src/Microsoft.AspNetCore.Mvc.Core/Routing/EndpointRoutingUrlHelper.cs
index 6f24248950..8ddd49c2f1 100644
--- a/src/Microsoft.AspNetCore.Mvc.Core/Routing/EndpointRoutingUrlHelper.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Core/Routing/EndpointRoutingUrlHelper.cs
@@ -15,21 +15,16 @@ namespace Microsoft.AspNetCore.Mvc.Routing
{
private readonly ILogger _logger;
private readonly LinkGenerator _linkGenerator;
- private readonly IEndpointFinder _routeValuesBasedEndpointFinder;
///
/// Initializes a new instance of the class using the specified
/// .
///
/// The for the current request.
- ///
- /// The which finds endpoints by required route values.
- ///
/// The used to generate the link.
/// The .
public EndpointRoutingUrlHelper(
ActionContext actionContext,
- IEndpointFinder routeValuesBasedEndpointFinder,
LinkGenerator linkGenerator,
ILogger logger)
: base(actionContext)
@@ -45,7 +40,6 @@ namespace Microsoft.AspNetCore.Mvc.Routing
}
_linkGenerator = linkGenerator;
- _routeValuesBasedEndpointFinder = routeValuesBasedEndpointFinder;
_logger = logger;
}
@@ -85,23 +79,10 @@ namespace Microsoft.AspNetCore.Mvc.Routing
valuesDictionary["controller"] = urlActionContext.Controller;
}
- var endpoints = _routeValuesBasedEndpointFinder.FindEndpoints(
- new RouteValuesAddress()
- {
- ExplicitValues = valuesDictionary,
- AmbientValues = AmbientValues
- });
-
var successfullyGeneratedLink = _linkGenerator.TryGetLink(
- new LinkGeneratorContext
- {
- HttpContext = ActionContext.HttpContext,
- Endpoints = endpoints,
- ExplicitValues = valuesDictionary,
- AmbientValues = AmbientValues
- },
+ ActionContext.HttpContext,
+ valuesDictionary,
out var link);
-
if (!successfullyGeneratedLink)
{
//TODO: log here
@@ -122,22 +103,10 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var valuesDictionary = routeContext.Values as RouteValueDictionary ?? GetValuesDictionary(routeContext.Values);
- var endpoints = _routeValuesBasedEndpointFinder.FindEndpoints(
- new RouteValuesAddress()
- {
- RouteName = routeContext.RouteName,
- ExplicitValues = valuesDictionary,
- AmbientValues = AmbientValues
- });
-
var successfullyGeneratedLink = _linkGenerator.TryGetLink(
- new LinkGeneratorContext
- {
- HttpContext = ActionContext.HttpContext,
- Endpoints = endpoints,
- ExplicitValues = valuesDictionary,
- AmbientValues = AmbientValues
- },
+ ActionContext.HttpContext,
+ routeContext.RouteName,
+ valuesDictionary,
out var link);
if (!successfullyGeneratedLink)
diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Routing/UrlHelperFactory.cs b/src/Microsoft.AspNetCore.Mvc.Core/Routing/UrlHelperFactory.cs
index fb6bbb0ae5..933f339f30 100644
--- a/src/Microsoft.AspNetCore.Mvc.Core/Routing/UrlHelperFactory.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Core/Routing/UrlHelperFactory.cs
@@ -51,12 +51,10 @@ namespace Microsoft.AspNetCore.Mvc.Routing
{
var services = httpContext.RequestServices;
var linkGenerator = services.GetRequiredService();
- var routeValuesBasedEndpointFinder = services.GetRequiredService>();
var logger = services.GetRequiredService>();
urlHelper = new EndpointRoutingUrlHelper(
context,
- routeValuesBasedEndpointFinder,
linkGenerator,
logger);
}
diff --git a/src/Microsoft.AspNetCore.Mvc.Cors/Internal/CorsApplicationModelProvider.cs b/src/Microsoft.AspNetCore.Mvc.Cors/Internal/CorsApplicationModelProvider.cs
index 3c5d23010d..352a8b4ee6 100644
--- a/src/Microsoft.AspNetCore.Mvc.Cors/Internal/CorsApplicationModelProvider.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Cors/Internal/CorsApplicationModelProvider.cs
@@ -6,7 +6,7 @@ using System.Linq;
using Microsoft.AspNetCore.Cors.Infrastructure;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.Internal;
-using Microsoft.AspNetCore.Routing.Metadata;
+using Microsoft.AspNetCore.Routing;
namespace Microsoft.AspNetCore.Mvc.Cors.Internal
{
diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/ControllerActionDescriptorProviderTests.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/ControllerActionDescriptorProviderTests.cs
index db7a1e3ce1..060543dd8b 100644
--- a/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/ControllerActionDescriptorProviderTests.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/ControllerActionDescriptorProviderTests.cs
@@ -14,7 +14,7 @@ using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Routing;
-using Microsoft.AspNetCore.Routing.Metadata;
+using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Options;
using Moq;
using Xunit;
diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/MvcEndpointDataSourceTests.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/MvcEndpointDataSourceTests.cs
index 6304099fc0..bc8d0dbcdc 100644
--- a/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/MvcEndpointDataSourceTests.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/MvcEndpointDataSourceTests.cs
@@ -66,7 +66,9 @@ namespace Microsoft.AspNetCore.Mvc.Internal
var endpoint = Assert.Single(endpoints);
var matcherEndpoint = Assert.IsType(endpoint);
- var endpointValue = matcherEndpoint.RequiredValues["Name"];
+ var routeValuesAddressMetadata = matcherEndpoint.Metadata.GetMetadata();
+ Assert.NotNull(routeValuesAddressMetadata);
+ var endpointValue = routeValuesAddressMetadata.RequiredValues["Name"];
Assert.Equal(routeValue, endpointValue);
Assert.Equal(displayName, matcherEndpoint.DisplayName);
@@ -389,7 +391,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
}
[Fact]
- public void Endpoints_ConventionalRoute_WithNoRouteName_DoesNotAddRouteNameMetadata()
+ public void Endpoints_ConventionalRoute_WithEmptyRouteName_CreatesMetadataWithEmptyRouteName()
{
// Arrange
var actionDescriptorCollection = GetActionDescriptorCollection(
@@ -404,8 +406,9 @@ namespace Microsoft.AspNetCore.Mvc.Internal
// Assert
var endpoint = Assert.Single(endpoints);
var matcherEndpoint = Assert.IsType(endpoint);
- var routeNameMetadata = matcherEndpoint.Metadata.GetMetadata();
- Assert.Null(routeNameMetadata);
+ var routeValuesAddressNameMetadata = matcherEndpoint.Metadata.GetMetadata();
+ Assert.NotNull(routeValuesAddressNameMetadata);
+ Assert.Equal(string.Empty, routeValuesAddressNameMetadata.Name);
}
[Fact]
@@ -428,17 +431,17 @@ namespace Microsoft.AspNetCore.Mvc.Internal
(ep) =>
{
var matcherEndpoint = Assert.IsType(ep);
- var routeNameMetadata = matcherEndpoint.Metadata.GetMetadata();
- Assert.NotNull(routeNameMetadata);
- Assert.Equal("namedRoute", routeNameMetadata.Name);
+ var routeValuesAddressMetadata = matcherEndpoint.Metadata.GetMetadata();
+ Assert.NotNull(routeValuesAddressMetadata);
+ Assert.Equal("namedRoute", routeValuesAddressMetadata.Name);
Assert.Equal("named/Home/Index/{id?}", matcherEndpoint.RoutePattern.RawText);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType(ep);
- var routeNameMetadata = matcherEndpoint.Metadata.GetMetadata();
- Assert.NotNull(routeNameMetadata);
- Assert.Equal("namedRoute", routeNameMetadata.Name);
+ var routeValuesAddressMetadata = matcherEndpoint.Metadata.GetMetadata();
+ Assert.NotNull(routeValuesAddressMetadata);
+ Assert.Equal("namedRoute", routeValuesAddressMetadata.Name);
Assert.Equal("named/Products/Details/{id?}", matcherEndpoint.RoutePattern.RawText);
});
}
diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/ActionConstraintMatcherPolicyTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/ActionConstraintMatcherPolicyTest.cs
index 77288f75d3..31e3dd8653 100644
--- a/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/ActionConstraintMatcherPolicyTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/ActionConstraintMatcherPolicyTest.cs
@@ -1,15 +1,11 @@
// Copyright (c) .NET Foundation. 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;
using System.Linq;
-using System.Reflection;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ActionConstraints;
-using Microsoft.AspNetCore.Mvc.ApplicationParts;
-using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Routing;
@@ -379,7 +375,6 @@ namespace Microsoft.AspNetCore.Mvc.Routing
return new MatcherEndpoint(
(r) => null,
RoutePatternFactory.Parse("/"),
- new RouteValueDictionary(),
0,
new EndpointMetadataCollection(metadata),
$"test: {action?.DisplayName}");
diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/ConsumesMatcherPolicyTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/ConsumesMatcherPolicyTest.cs
index d52ddebf74..48a49e465e 100644
--- a/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/ConsumesMatcherPolicyTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/ConsumesMatcherPolicyTest.cs
@@ -223,7 +223,6 @@ namespace Microsoft.AspNetCore.Mvc.Routing
return new MatcherEndpoint(
(next) => null,
RoutePatternFactory.Parse(template),
- new RouteValueDictionary(),
0,
new EndpointMetadataCollection(metadata),
$"test: {template} - {string.Join(", ", consumesMetadata?.ContentTypes ?? Array.Empty())}");
diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/EndpointRoutingUrlHelperTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/EndpointRoutingUrlHelperTest.cs
index 867832e808..e02dd3c5c9 100644
--- a/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/EndpointRoutingUrlHelperTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/EndpointRoutingUrlHelperTest.cs
@@ -56,7 +56,17 @@ namespace Microsoft.AspNetCore.Mvc.Routing
requiredValues: new { controller = "Orders", action = "GetAll" },
routeName: "OrdersApi");
var urlHelper = CreateUrlHelper(new[] { endpoint1, endpoint2 });
- urlHelper.ActionContext.RouteData.Values["id"] = "500";
+
+ // Set the endpoint feature and current context just as a normal request to MVC app would be
+ var endpointFeature = new EndpointFeature();
+ urlHelper.ActionContext.HttpContext.Features.Set(endpointFeature);
+ endpointFeature.Endpoint = endpoint1;
+ endpointFeature.Values = new RouteValueDictionary
+ {
+ ["controller"] = "Orders",
+ ["action"] = "GetById",
+ ["id"] = "500"
+ };
// Act
var url = urlHelper.RouteUrl(
@@ -132,7 +142,6 @@ namespace Microsoft.AspNetCore.Mvc.Routing
endpoints.Add(new MatcherEndpoint(
next => httpContext => Task.CompletedTask,
RoutePatternFactory.Parse(template),
- new RouteValueDictionary(),
0,
EndpointMetadataCollection.Empty,
null));
@@ -147,7 +156,6 @@ namespace Microsoft.AspNetCore.Mvc.Routing
Endpoint = new MatcherEndpoint(
next => cntxt => Task.CompletedTask,
RoutePatternFactory.Parse("/"),
- new RouteValueDictionary(),
0,
EndpointMetadataCollection.Empty,
null)
@@ -280,17 +288,13 @@ namespace Microsoft.AspNetCore.Mvc.Routing
{
if (metadataCollection == null)
{
- metadataCollection = EndpointMetadataCollection.Empty;
- if (!string.IsNullOrEmpty(routeName))
- {
- metadataCollection = new EndpointMetadataCollection(new[] { new RouteNameMetadata(routeName) });
- }
+ metadataCollection = new EndpointMetadataCollection(
+ new RouteValuesAddressMetadata(routeName, new RouteValueDictionary(requiredValues)));
}
return new MatcherEndpoint(
next => (httpContext) => Task.CompletedTask,
RoutePatternFactory.Parse(template, defaults, constraints: null),
- new RouteValueDictionary(requiredValues),
order,
metadataCollection,
null);
@@ -316,22 +320,11 @@ namespace Microsoft.AspNetCore.Mvc.Routing
return new MatcherEndpoint(
next => c => Task.CompletedTask,
RoutePatternFactory.Parse(template, defaults, constraints: null),
- new RouteValueDictionary(),
0,
EndpointMetadataCollection.Empty,
null);
}
- private class RouteNameMetadata : IRouteNameMetadata
- {
- public RouteNameMetadata(string routeName)
- {
- Name = routeName;
- }
-
- public string Name { get; }
- }
-
private class SuppressLinkGenerationMetadata : ISuppressLinkGenerationMetadata { }
}
}
diff --git a/test/Microsoft.AspNetCore.Mvc.Cors.Test/Internal/CorsApplicationModelProviderTest.cs b/test/Microsoft.AspNetCore.Mvc.Cors.Test/Internal/CorsApplicationModelProviderTest.cs
index a9538a9b24..4543e2e8cd 100644
--- a/test/Microsoft.AspNetCore.Mvc.Cors.Test/Internal/CorsApplicationModelProviderTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Cors.Test/Internal/CorsApplicationModelProviderTest.cs
@@ -11,7 +11,7 @@ using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.ModelBinding;
-using Microsoft.AspNetCore.Routing.Metadata;
+using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Moq;