Remove obsolete APIs from routing (#7371)
This commit is contained in:
parent
63a8b14619
commit
c2d1ab925e
|
|
@ -21,17 +21,15 @@ namespace Microsoft.AspNetCore.Routing
|
|||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DefaultInlineConstraintResolver"/> class.
|
||||
/// </summary>
|
||||
/// <param name="routeOptions">
|
||||
/// Accessor for <see cref="RouteOptions"/> containing the constraints of interest.
|
||||
/// </param>
|
||||
[Obsolete("This constructor is obsolete. Use DefaultInlineConstraintResolver.ctor(IOptions<RouteOptions>, IServiceProvider) instead.")]
|
||||
public DefaultInlineConstraintResolver(IOptions<RouteOptions> routeOptions)
|
||||
{
|
||||
_inlineConstraintMap = routeOptions.Value.ConstraintMap;
|
||||
}
|
||||
|
||||
/// <param name="routeOptions">Accessor for <see cref="RouteOptions"/> containing the constraints of interest.</param>
|
||||
/// <param name="serviceProvider">The <see cref="IServiceProvider"/> to get service arguments from.</param>
|
||||
public DefaultInlineConstraintResolver(IOptions<RouteOptions> routeOptions, IServiceProvider serviceProvider)
|
||||
{
|
||||
if (routeOptions == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routeOptions));
|
||||
}
|
||||
|
||||
if (serviceProvider == null)
|
||||
{
|
||||
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 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>
|
||||
/// Initializes a new instance of <see cref="TreeRouteBuilder"/>.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -325,33 +325,12 @@ namespace Microsoft.AspNetCore.Routing.Tests
|
|||
ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
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)
|
||||
private IInlineConstraintResolver GetInlineConstraintResolver(RouteOptions routeOptions)
|
||||
{
|
||||
var optionsAccessor = new Mock<IOptions<RouteOptions>>();
|
||||
optionsAccessor.SetupGet(o => o.Value).Returns(routeOptions);
|
||||
|
||||
if (hasServiceProvider)
|
||||
{
|
||||
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
|
||||
return new DefaultInlineConstraintResolver(optionsAccessor.Object, new TestServiceProvider());
|
||||
}
|
||||
|
||||
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(
|
||||
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]
|
||||
[InlineData("template/5", "template/{parameter:int}")]
|
||||
[InlineData("template/5", "template/{parameter}")]
|
||||
|
|
@ -2151,23 +2087,6 @@ namespace Microsoft.AspNetCore.Routing.Tree
|
|||
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(
|
||||
string firstTemplate,
|
||||
string secondTemplate)
|
||||
|
|
|
|||
|
|
@ -174,9 +174,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
|||
.SetupGet(o => o.Value)
|
||||
.Returns(new RouteOptions());
|
||||
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
var inlineConstraintResolver = new DefaultInlineConstraintResolver(routeOptions.Object);
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
var inlineConstraintResolver = new DefaultInlineConstraintResolver(routeOptions.Object, Mock.Of<IServiceProvider>());
|
||||
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IInlineConstraintResolver>(inlineConstraintResolver);
|
||||
|
|
|
|||
Loading…
Reference in New Issue