Remove obsolete APIs from routing (#7371)
This commit is contained in:
parent
63a8b14619
commit
c2d1ab925e
|
|
@ -21,17 +21,15 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="DefaultInlineConstraintResolver"/> class.
|
/// Initializes a new instance of the <see cref="DefaultInlineConstraintResolver"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="routeOptions">
|
/// <param name="routeOptions">Accessor for <see cref="RouteOptions"/> containing the constraints of interest.</param>
|
||||||
/// Accessor for <see cref="RouteOptions"/> containing the constraints of interest.
|
/// <param name="serviceProvider">The <see cref="IServiceProvider"/> to get service arguments from.</param>
|
||||||
/// </param>
|
|
||||||
[Obsolete("This constructor is obsolete. Use DefaultInlineConstraintResolver.ctor(IOptions<RouteOptions>, IServiceProvider) instead.")]
|
|
||||||
public DefaultInlineConstraintResolver(IOptions<RouteOptions> routeOptions)
|
|
||||||
{
|
|
||||||
_inlineConstraintMap = routeOptions.Value.ConstraintMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DefaultInlineConstraintResolver(IOptions<RouteOptions> routeOptions, IServiceProvider serviceProvider)
|
public DefaultInlineConstraintResolver(IOptions<RouteOptions> routeOptions, IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
|
if (routeOptions == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(routeOptions));
|
||||||
|
}
|
||||||
|
|
||||||
if (serviceProvider == null)
|
if (serviceProvider == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(serviceProvider));
|
throw new ArgumentNullException(nameof(serviceProvider));
|
||||||
|
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
// 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;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Routing
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Represents metadata used during link generation to find
|
|
||||||
/// the associated endpoint using route values.
|
|
||||||
/// </summary>
|
|
||||||
[Obsolete("Route values are now specified on a RoutePattern.")]
|
|
||||||
public interface IRouteValuesAddressMetadata
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the route name. Can be null.
|
|
||||||
/// </summary>
|
|
||||||
string RouteName { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the required route values.
|
|
||||||
/// </summary>
|
|
||||||
IReadOnlyDictionary<string, object> RequiredValues { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,88 +0,0 @@
|
||||||
// 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.Collections.ObjectModel;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Routing
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Metadata used during link generation to find the associated endpoint using route values.
|
|
||||||
/// </summary>
|
|
||||||
[DebuggerDisplay("{DebuggerToString(),nq}")]
|
|
||||||
[Obsolete("Route values are now specified on a RoutePattern.")]
|
|
||||||
public sealed class RouteValuesAddressMetadata : IRouteValuesAddressMetadata
|
|
||||||
{
|
|
||||||
private static readonly IReadOnlyDictionary<string, object> EmptyRouteValues =
|
|
||||||
new ReadOnlyDictionary<string, object>(new Dictionary<string, object>());
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new instance of <see cref="RouteValuesAddressMetadata"/> with the provided route name.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="routeName">The route name. Can be null.</param>
|
|
||||||
public RouteValuesAddressMetadata(string routeName) : this(routeName, EmptyRouteValues)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new instance of <see cref="RouteValuesAddressMetadata"/> with the provided required route values.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="requiredValues">The required route values.</param>
|
|
||||||
public RouteValuesAddressMetadata(IReadOnlyDictionary<string, object> requiredValues) : this(null, requiredValues)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new instance of <see cref="RouteValuesAddressMetadata"/> with the provided route name and required route values.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="routeName">The route name. Can be null.</param>
|
|
||||||
/// <param name="requiredValues">The required route values.</param>
|
|
||||||
public RouteValuesAddressMetadata(string routeName, IReadOnlyDictionary<string, object> requiredValues)
|
|
||||||
{
|
|
||||||
if (requiredValues == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(requiredValues));
|
|
||||||
}
|
|
||||||
|
|
||||||
RouteName = routeName;
|
|
||||||
RequiredValues = requiredValues;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the route name. Can be null.
|
|
||||||
/// </summary>
|
|
||||||
public string RouteName { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the required route values.
|
|
||||||
/// </summary>
|
|
||||||
public IReadOnlyDictionary<string, object> RequiredValues { get; }
|
|
||||||
|
|
||||||
internal string DebuggerToString()
|
|
||||||
{
|
|
||||||
return $"Name: {RouteName} - Required values: {string.Join(", ", FormatValues(RequiredValues))}";
|
|
||||||
|
|
||||||
IEnumerable<string> FormatValues(IEnumerable<KeyValuePair<string, object>> values)
|
|
||||||
{
|
|
||||||
if (values == null)
|
|
||||||
{
|
|
||||||
return Array.Empty<string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
return values.Select(
|
|
||||||
kvp =>
|
|
||||||
{
|
|
||||||
var value = "null";
|
|
||||||
if (kvp.Value != null)
|
|
||||||
{
|
|
||||||
value = "\"" + kvp.Value.ToString() + "\"";
|
|
||||||
}
|
|
||||||
return kvp.Key + " = " + value;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -24,34 +24,6 @@ namespace Microsoft.AspNetCore.Routing.Tree
|
||||||
private readonly ObjectPool<UriBuildingContext> _objectPool;
|
private readonly ObjectPool<UriBuildingContext> _objectPool;
|
||||||
private readonly IInlineConstraintResolver _constraintResolver;
|
private readonly IInlineConstraintResolver _constraintResolver;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <para>
|
|
||||||
/// This constructor is obsolete and will be removed in a future version. The recommended
|
|
||||||
/// alternative is the overload that does not take a UrlEncoder.
|
|
||||||
/// </para>
|
|
||||||
/// <para>Initializes a new instance of <see cref="TreeRouteBuilder"/>.</para>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
|
|
||||||
/// <param name="urlEncoder">The <see cref="UrlEncoder"/>.</param>
|
|
||||||
/// <param name="objectPool">The <see cref="ObjectPool{UrlBuildingContext}"/>.</param>
|
|
||||||
/// <param name="constraintResolver">The <see cref="IInlineConstraintResolver"/>.</param>
|
|
||||||
[Obsolete("This constructor is obsolete and will be removed in a future version. The recommended " +
|
|
||||||
"alternative is the overload that does not take a UrlEncoder.")]
|
|
||||||
public TreeRouteBuilder(
|
|
||||||
ILoggerFactory loggerFactory,
|
|
||||||
UrlEncoder urlEncoder,
|
|
||||||
ObjectPool<UriBuildingContext> objectPool,
|
|
||||||
IInlineConstraintResolver constraintResolver)
|
|
||||||
: this(loggerFactory, objectPool, constraintResolver)
|
|
||||||
{
|
|
||||||
if (urlEncoder == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(urlEncoder));
|
|
||||||
}
|
|
||||||
|
|
||||||
_urlEncoder = urlEncoder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of <see cref="TreeRouteBuilder"/>.
|
/// Initializes a new instance of <see cref="TreeRouteBuilder"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -325,33 +325,12 @@ namespace Microsoft.AspNetCore.Routing.Tests
|
||||||
ex.Message);
|
ex.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
private IInlineConstraintResolver GetInlineConstraintResolver(RouteOptions routeOptions)
|
||||||
public void ResolveConstraint_HasArguments_NoServiceProvider()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var routeOptions = new RouteOptions();
|
|
||||||
var constraintResolver = GetInlineConstraintResolver(routeOptions, hasServiceProvider: false);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var constraint = constraintResolver.ResolveConstraint("regex(ab,1)");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.IsType<RegexInlineRouteConstraint>(constraint);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IInlineConstraintResolver GetInlineConstraintResolver(RouteOptions routeOptions, bool hasServiceProvider = true)
|
|
||||||
{
|
{
|
||||||
var optionsAccessor = new Mock<IOptions<RouteOptions>>();
|
var optionsAccessor = new Mock<IOptions<RouteOptions>>();
|
||||||
optionsAccessor.SetupGet(o => o.Value).Returns(routeOptions);
|
optionsAccessor.SetupGet(o => o.Value).Returns(routeOptions);
|
||||||
|
|
||||||
if (hasServiceProvider)
|
return new DefaultInlineConstraintResolver(optionsAccessor.Object, new TestServiceProvider());
|
||||||
{
|
|
||||||
return new DefaultInlineConstraintResolver(optionsAccessor.Object, new TestServiceProvider());
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma warning disable CS0618 // Type or member is obsolete
|
|
||||||
return new DefaultInlineConstraintResolver(optionsAccessor.Object);
|
|
||||||
#pragma warning restore CS0618 // Type or member is obsolete
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class MultiConstructorRouteConstraint : IRouteConstraint
|
private class MultiConstructorRouteConstraint : IRouteConstraint
|
||||||
|
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
// 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.Text;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Routing
|
|
||||||
{
|
|
||||||
public class RouteValuesAddressMetadataTests
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public void DebuggerToString_NoNameAndRequiredValues_ReturnsString()
|
|
||||||
{
|
|
||||||
#pragma warning disable CS0618 // Type or member is obsolete
|
|
||||||
var metadata = new RouteValuesAddressMetadata(null, new Dictionary<string, object>());
|
|
||||||
#pragma warning restore CS0618 // Type or member is obsolete
|
|
||||||
|
|
||||||
Assert.Equal("Name: - Required values: ", metadata.DebuggerToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void DebuggerToString_HasNameAndRequiredValues_ReturnsString()
|
|
||||||
{
|
|
||||||
#pragma warning disable CS0618 // Type or member is obsolete
|
|
||||||
var metadata = new RouteValuesAddressMetadata("Name!", new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
["requiredValue1"] = "One",
|
|
||||||
["requiredValue2"] = 2,
|
|
||||||
});
|
|
||||||
#pragma warning restore CS0618 // Type or member is obsolete
|
|
||||||
|
|
||||||
Assert.Equal("Name: Name! - Required values: requiredValue1 = \"One\", requiredValue2 = \"2\"", metadata.DebuggerToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -26,70 +26,6 @@ namespace Microsoft.AspNetCore.Routing.Tree
|
||||||
private static ObjectPool<UriBuildingContext> Pool = new DefaultObjectPoolProvider().Create(
|
private static ObjectPool<UriBuildingContext> Pool = new DefaultObjectPoolProvider().Create(
|
||||||
new UriBuilderContextPooledObjectPolicy());
|
new UriBuilderContextPooledObjectPolicy());
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task TreeRouter_RouteAsync_MatchesCatchAllRoutesWithDefaults_UsingObsoleteConstructo()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var routes = new[] {
|
|
||||||
"{parameter1=1}/{parameter2=2}/{parameter3=3}/{*parameter4=4}",
|
|
||||||
};
|
|
||||||
var url = "/a/b/c";
|
|
||||||
var routeValues = new[] { "a", "b", "c", "4" };
|
|
||||||
|
|
||||||
var expectedRouteGroup = CreateRouteGroup(0, "{parameter1=1}/{parameter2=2}/{parameter3=3}/{*parameter4=4}");
|
|
||||||
var routeValueKeys = new[] { "parameter1", "parameter2", "parameter3", "parameter4" };
|
|
||||||
var expectedRouteValues = new RouteValueDictionary();
|
|
||||||
for (var i = 0; i < routeValueKeys.Length; i++)
|
|
||||||
{
|
|
||||||
expectedRouteValues.Add(routeValueKeys[i], routeValues[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
var builder = CreateBuilderUsingObsoleteConstructor();
|
|
||||||
|
|
||||||
// We setup the route entries in reverse order of precedence to ensure that when we
|
|
||||||
// try to route the request, the route with a higher precedence gets tried first.
|
|
||||||
foreach (var template in routes.Reverse())
|
|
||||||
{
|
|
||||||
MapInboundEntry(builder, template);
|
|
||||||
}
|
|
||||||
|
|
||||||
var route = builder.Build();
|
|
||||||
|
|
||||||
var context = CreateRouteContext(url);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await route.RouteAsync(context);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Equal(expectedRouteGroup, context.RouteData.Values["test_route_group"]);
|
|
||||||
foreach (var entry in expectedRouteValues)
|
|
||||||
{
|
|
||||||
var data = Assert.Single(context.RouteData.Values, v => v.Key == entry.Key);
|
|
||||||
Assert.Equal(entry.Value, data.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task TreeRouter_RouteAsync_DoesNotMatchRoutesWithIntermediateDefaultRouteValues_UsingObsoleteConstructor()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var url = "/a/b";
|
|
||||||
|
|
||||||
var builder = CreateBuilderUsingObsoleteConstructor();
|
|
||||||
|
|
||||||
MapInboundEntry(builder, "a/b/{parameter3=3}/d");
|
|
||||||
|
|
||||||
var route = builder.Build();
|
|
||||||
|
|
||||||
var context = CreateRouteContext(url);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await route.RouteAsync(context);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Null(context.Handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("template/5", "template/{parameter:int}")]
|
[InlineData("template/5", "template/{parameter:int}")]
|
||||||
[InlineData("template/5", "template/{parameter}")]
|
[InlineData("template/5", "template/{parameter}")]
|
||||||
|
|
@ -2151,23 +2087,6 @@ namespace Microsoft.AspNetCore.Routing.Tree
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TreeRouteBuilder CreateBuilderUsingObsoleteConstructor()
|
|
||||||
{
|
|
||||||
var objectPoolProvider = new DefaultObjectPoolProvider();
|
|
||||||
var objectPolicy = new UriBuilderContextPooledObjectPolicy();
|
|
||||||
var objectPool = objectPoolProvider.Create<UriBuildingContext>(objectPolicy);
|
|
||||||
|
|
||||||
var constraintResolver = CreateConstraintResolver();
|
|
||||||
#pragma warning disable CS0618 // Type or member is obsolete
|
|
||||||
var builder = new TreeRouteBuilder(
|
|
||||||
NullLoggerFactory.Instance,
|
|
||||||
UrlEncoder.Default,
|
|
||||||
objectPool,
|
|
||||||
constraintResolver);
|
|
||||||
#pragma warning restore CS0618 // Type or member is obsolete
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static TreeRouter CreateTreeRouter(
|
private static TreeRouter CreateTreeRouter(
|
||||||
string firstTemplate,
|
string firstTemplate,
|
||||||
string secondTemplate)
|
string secondTemplate)
|
||||||
|
|
|
||||||
|
|
@ -174,9 +174,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
.SetupGet(o => o.Value)
|
.SetupGet(o => o.Value)
|
||||||
.Returns(new RouteOptions());
|
.Returns(new RouteOptions());
|
||||||
|
|
||||||
#pragma warning disable CS0618 // Type or member is obsolete
|
var inlineConstraintResolver = new DefaultInlineConstraintResolver(routeOptions.Object, Mock.Of<IServiceProvider>());
|
||||||
var inlineConstraintResolver = new DefaultInlineConstraintResolver(routeOptions.Object);
|
|
||||||
#pragma warning restore CS0618 // Type or member is obsolete
|
|
||||||
|
|
||||||
var services = new ServiceCollection()
|
var services = new ServiceCollection()
|
||||||
.AddSingleton<IInlineConstraintResolver>(inlineConstraintResolver);
|
.AddSingleton<IInlineConstraintResolver>(inlineConstraintResolver);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue