React to routing cleanup
This commit is contained in:
parent
d9141d6bf8
commit
87704c67e1
|
|
@ -4,43 +4,34 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.Encodings.Web;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Mvc.Abstractions;
|
using Microsoft.AspNetCore.Mvc.Abstractions;
|
||||||
using Microsoft.AspNetCore.Mvc.Core;
|
using Microsoft.AspNetCore.Mvc.Core;
|
||||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||||
using Microsoft.AspNetCore.Mvc.Routing;
|
using Microsoft.AspNetCore.Mvc.Routing;
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
using Microsoft.AspNetCore.Routing.Internal;
|
|
||||||
using Microsoft.AspNetCore.Routing.Template;
|
using Microsoft.AspNetCore.Routing.Template;
|
||||||
using Microsoft.AspNetCore.Routing.Tree;
|
using Microsoft.AspNetCore.Routing.Tree;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.ObjectPool;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.Internal
|
namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
{
|
{
|
||||||
public class AttributeRoute : IRouter
|
public class AttributeRoute : IRouter
|
||||||
{
|
{
|
||||||
private readonly IRouter _target;
|
private readonly IRouter _handler;
|
||||||
private readonly IActionDescriptorCollectionProvider _actionDescriptorCollectionProvider;
|
private readonly IActionDescriptorCollectionProvider _actionDescriptorCollectionProvider;
|
||||||
private readonly IInlineConstraintResolver _constraintResolver;
|
private readonly IServiceProvider _services;
|
||||||
private readonly ObjectPool<UriBuildingContext> _contextPool;
|
|
||||||
private readonly UrlEncoder _urlEncoder;
|
|
||||||
private readonly ILoggerFactory _loggerFactory;
|
|
||||||
|
|
||||||
private TreeRouter _router;
|
private TreeRouter _router;
|
||||||
|
|
||||||
public AttributeRoute(
|
public AttributeRoute(
|
||||||
IRouter target,
|
IRouter handler,
|
||||||
IActionDescriptorCollectionProvider actionDescriptorCollectionProvider,
|
IActionDescriptorCollectionProvider actionDescriptorCollectionProvider,
|
||||||
IInlineConstraintResolver constraintResolver,
|
IServiceProvider services)
|
||||||
ObjectPool<UriBuildingContext> contextPool,
|
|
||||||
UrlEncoder urlEncoder,
|
|
||||||
ILoggerFactory loggerFactory)
|
|
||||||
{
|
{
|
||||||
if (target == null)
|
if (handler == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(target));
|
throw new ArgumentNullException(nameof(handler));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionDescriptorCollectionProvider == null)
|
if (actionDescriptorCollectionProvider == null)
|
||||||
|
|
@ -48,32 +39,14 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
throw new ArgumentNullException(nameof(actionDescriptorCollectionProvider));
|
throw new ArgumentNullException(nameof(actionDescriptorCollectionProvider));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (constraintResolver == null)
|
if (services == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(constraintResolver));
|
throw new ArgumentNullException(nameof(services));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (contextPool == null)
|
_handler = handler;
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(contextPool));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (urlEncoder == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(urlEncoder));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loggerFactory == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(loggerFactory));
|
|
||||||
}
|
|
||||||
|
|
||||||
_target = target;
|
|
||||||
_actionDescriptorCollectionProvider = actionDescriptorCollectionProvider;
|
_actionDescriptorCollectionProvider = actionDescriptorCollectionProvider;
|
||||||
_constraintResolver = constraintResolver;
|
_services = services;
|
||||||
_contextPool = contextPool;
|
|
||||||
_urlEncoder = urlEncoder;
|
|
||||||
_loggerFactory = loggerFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
@ -98,38 +71,29 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
// it on startup.
|
// it on startup.
|
||||||
if (_router == null || _router.Version != actions.Version)
|
if (_router == null || _router.Version != actions.Version)
|
||||||
{
|
{
|
||||||
var entries = GetEntries(actions);
|
var builder = _services.GetRequiredService<TreeRouteBuilder>();
|
||||||
_router = BuildRoute(entries, actions.Version);
|
AddEntries(builder, actions);
|
||||||
|
_router = builder.Build(actions.Version);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _router;
|
return _router;
|
||||||
}
|
}
|
||||||
|
|
||||||
// internal for testing
|
// internal for testing
|
||||||
internal AttributeRouteEntries GetEntries(ActionDescriptorCollection actions)
|
internal void AddEntries(TreeRouteBuilder builder, ActionDescriptorCollection actions)
|
||||||
{
|
{
|
||||||
var entries = new AttributeRouteEntries();
|
var routeInfos = GetRouteInfos(actions.Items);
|
||||||
|
|
||||||
var routeInfos = GetRouteInfos(_constraintResolver, actions.Items);
|
|
||||||
|
|
||||||
// We're creating one TreeRouteLinkGenerationEntry per action. This allows us to match the intended
|
// We're creating one TreeRouteLinkGenerationEntry per action. This allows us to match the intended
|
||||||
// action by expected route values, and then use the TemplateBinder to generate the link.
|
// action by expected route values, and then use the TemplateBinder to generate the link.
|
||||||
foreach (var routeInfo in routeInfos)
|
foreach (var routeInfo in routeInfos)
|
||||||
{
|
{
|
||||||
entries.LinkGenerationEntries.Add(new TreeRouteLinkGenerationEntry()
|
builder.MapOutbound(
|
||||||
{
|
_handler,
|
||||||
// Using routeInfo.Defaults here WITHOUT adding the RouteGroupKey. We don't want to impact the
|
routeInfo.RouteTemplate,
|
||||||
// behavior of link generation.
|
new RouteValueDictionary(routeInfo.ActionDescriptor.RouteValueDefaults),
|
||||||
Binder = new TemplateBinder(_urlEncoder, _contextPool, routeInfo.ParsedTemplate, routeInfo.Defaults),
|
routeInfo.RouteName,
|
||||||
Defaults = routeInfo.Defaults,
|
routeInfo.Order);
|
||||||
Constraints = routeInfo.Constraints,
|
|
||||||
Order = routeInfo.Order,
|
|
||||||
GenerationPrecedence = routeInfo.GenerationPrecedence,
|
|
||||||
RequiredLinkValues = routeInfo.ActionDescriptor.RouteValueDefaults,
|
|
||||||
RouteGroup = routeInfo.RouteGroup,
|
|
||||||
Template = routeInfo.ParsedTemplate,
|
|
||||||
Name = routeInfo.Name,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We're creating one AttributeRouteMatchingEntry per group, so we need to identify the distinct set of
|
// We're creating one AttributeRouteMatchingEntry per group, so we need to identify the distinct set of
|
||||||
|
|
@ -143,39 +107,14 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
//
|
//
|
||||||
// We then inject the route group as a default for the matcher so it gets passed back to MVC
|
// We then inject the route group as a default for the matcher so it gets passed back to MVC
|
||||||
// for use in action selection.
|
// for use in action selection.
|
||||||
var defaults = new RouteValueDictionary(routeInfo.Defaults);
|
var entry = builder.MapInbound(
|
||||||
defaults[TreeRouter.RouteGroupKey] = routeInfo.RouteGroup;
|
_handler,
|
||||||
|
routeInfo.RouteTemplate,
|
||||||
|
routeInfo.RouteName,
|
||||||
|
routeInfo.Order);
|
||||||
|
|
||||||
entries.MatchingEntries.Add(new TreeRouteMatchingEntry()
|
entry.Defaults[TreeRouter.RouteGroupKey] = routeInfo.RouteGroup;
|
||||||
{
|
|
||||||
Order = routeInfo.Order,
|
|
||||||
Precedence = routeInfo.MatchPrecedence,
|
|
||||||
Target = _target,
|
|
||||||
RouteName = routeInfo.Name,
|
|
||||||
RouteTemplate = routeInfo.ParsedTemplate,
|
|
||||||
TemplateMatcher = new TemplateMatcher(routeInfo.ParsedTemplate, defaults),
|
|
||||||
Constraints = routeInfo.Constraints,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
private TreeRouter BuildRoute(AttributeRouteEntries entries, int version)
|
|
||||||
{
|
|
||||||
var routeBuilder = new TreeRouteBuilder(_target, _loggerFactory);
|
|
||||||
|
|
||||||
foreach (var entry in entries.LinkGenerationEntries)
|
|
||||||
{
|
|
||||||
routeBuilder.Add(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var entry in entries.MatchingEntries)
|
|
||||||
{
|
|
||||||
routeBuilder.Add(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
return routeBuilder.Build(version);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IEnumerable<RouteInfo> GroupRouteInfosByGroupId(List<RouteInfo> routeInfos)
|
private static IEnumerable<RouteInfo> GroupRouteInfosByGroupId(List<RouteInfo> routeInfos)
|
||||||
|
|
@ -193,9 +132,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
return routeInfosByGroupId.Values;
|
return routeInfosByGroupId.Values;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<RouteInfo> GetRouteInfos(
|
private static List<RouteInfo> GetRouteInfos(IReadOnlyList<ActionDescriptor> actions)
|
||||||
IInlineConstraintResolver constraintResolver,
|
|
||||||
IReadOnlyList<ActionDescriptor> actions)
|
|
||||||
{
|
{
|
||||||
var routeInfos = new List<RouteInfo>();
|
var routeInfos = new List<RouteInfo>();
|
||||||
var errors = new List<RouteInfo>();
|
var errors = new List<RouteInfo>();
|
||||||
|
|
@ -210,7 +147,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
var attributeRoutedActions = actions.Where(a => a.AttributeRouteInfo?.Template != null);
|
var attributeRoutedActions = actions.Where(a => a.AttributeRouteInfo?.Template != null);
|
||||||
foreach (var action in attributeRoutedActions)
|
foreach (var action in attributeRoutedActions)
|
||||||
{
|
{
|
||||||
var routeInfo = GetRouteInfo(constraintResolver, templateCache, action);
|
var routeInfo = GetRouteInfo(templateCache, action);
|
||||||
if (routeInfo.ErrorMessage == null)
|
if (routeInfo.ErrorMessage == null)
|
||||||
{
|
{
|
||||||
routeInfos.Add(routeInfo);
|
routeInfos.Add(routeInfo);
|
||||||
|
|
@ -239,7 +176,6 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
}
|
}
|
||||||
|
|
||||||
private static RouteInfo GetRouteInfo(
|
private static RouteInfo GetRouteInfo(
|
||||||
IInlineConstraintResolver constraintResolver,
|
|
||||||
Dictionary<string, RouteTemplate> templateCache,
|
Dictionary<string, RouteTemplate> templateCache,
|
||||||
ActionDescriptor action)
|
ActionDescriptor action)
|
||||||
{
|
{
|
||||||
|
|
@ -261,7 +197,6 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
{
|
{
|
||||||
ActionDescriptor = action,
|
ActionDescriptor = action,
|
||||||
RouteGroup = constraint.RouteValue,
|
RouteGroup = constraint.RouteValue,
|
||||||
RouteTemplate = action.AttributeRouteInfo.Template,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|
@ -274,7 +209,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
templateCache.Add(action.AttributeRouteInfo.Template, parsedTemplate);
|
templateCache.Add(action.AttributeRouteInfo.Template, parsedTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
routeInfo.ParsedTemplate = parsedTemplate;
|
routeInfo.RouteTemplate = parsedTemplate;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -284,12 +219,12 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
|
|
||||||
foreach (var kvp in action.RouteValueDefaults)
|
foreach (var kvp in action.RouteValueDefaults)
|
||||||
{
|
{
|
||||||
foreach (var parameter in routeInfo.ParsedTemplate.Parameters)
|
foreach (var parameter in routeInfo.RouteTemplate.Parameters)
|
||||||
{
|
{
|
||||||
if (string.Equals(kvp.Key, parameter.Name, StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(kvp.Key, parameter.Name, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
routeInfo.ErrorMessage = Resources.FormatAttributeRoute_CannotContainParameter(
|
routeInfo.ErrorMessage = Resources.FormatAttributeRoute_CannotContainParameter(
|
||||||
routeInfo.RouteTemplate,
|
routeInfo.RouteTemplate.TemplateText,
|
||||||
kvp.Key,
|
kvp.Key,
|
||||||
kvp.Value);
|
kvp.Value);
|
||||||
|
|
||||||
|
|
@ -299,40 +234,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
}
|
}
|
||||||
|
|
||||||
routeInfo.Order = action.AttributeRouteInfo.Order;
|
routeInfo.Order = action.AttributeRouteInfo.Order;
|
||||||
|
routeInfo.RouteName = action.AttributeRouteInfo.Name;
|
||||||
routeInfo.MatchPrecedence = RoutePrecedence.ComputeMatched(routeInfo.ParsedTemplate);
|
|
||||||
routeInfo.GenerationPrecedence = RoutePrecedence.ComputeGenerated(routeInfo.ParsedTemplate);
|
|
||||||
|
|
||||||
routeInfo.Name = action.AttributeRouteInfo.Name;
|
|
||||||
|
|
||||||
var constraintBuilder = new RouteConstraintBuilder(constraintResolver, routeInfo.RouteTemplate);
|
|
||||||
|
|
||||||
foreach (var parameter in routeInfo.ParsedTemplate.Parameters)
|
|
||||||
{
|
|
||||||
if (parameter.InlineConstraints != null)
|
|
||||||
{
|
|
||||||
if (parameter.IsOptional)
|
|
||||||
{
|
|
||||||
constraintBuilder.SetOptional(parameter.Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var inlineConstraint in parameter.InlineConstraints)
|
|
||||||
{
|
|
||||||
constraintBuilder.AddResolvedConstraint(parameter.Name, inlineConstraint.Constraint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
routeInfo.Constraints = constraintBuilder.Build();
|
|
||||||
|
|
||||||
routeInfo.Defaults = new RouteValueDictionary();
|
|
||||||
foreach (var parameter in routeInfo.ParsedTemplate.Parameters)
|
|
||||||
{
|
|
||||||
if (parameter.DefaultValue != null)
|
|
||||||
{
|
|
||||||
routeInfo.Defaults.Add(parameter.Name, parameter.DefaultValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return routeInfo;
|
return routeInfo;
|
||||||
}
|
}
|
||||||
|
|
@ -341,25 +243,15 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
{
|
{
|
||||||
public ActionDescriptor ActionDescriptor { get; set; }
|
public ActionDescriptor ActionDescriptor { get; set; }
|
||||||
|
|
||||||
public IDictionary<string, IRouteConstraint> Constraints { get; set; }
|
|
||||||
|
|
||||||
public RouteValueDictionary Defaults { get; set; }
|
|
||||||
|
|
||||||
public string ErrorMessage { get; set; }
|
public string ErrorMessage { get; set; }
|
||||||
|
|
||||||
public RouteTemplate ParsedTemplate { get; set; }
|
|
||||||
|
|
||||||
public int Order { get; set; }
|
public int Order { get; set; }
|
||||||
|
|
||||||
public decimal MatchPrecedence { get; set; }
|
|
||||||
|
|
||||||
public decimal GenerationPrecedence { get; set; }
|
|
||||||
|
|
||||||
public string RouteGroup { get; set; }
|
public string RouteGroup { get; set; }
|
||||||
|
|
||||||
public string RouteTemplate { get; set; }
|
public string RouteName { get; set; }
|
||||||
|
|
||||||
public string Name { get; set; }
|
public RouteTemplate RouteTemplate { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
{
|
{
|
||||||
public class AttributeRouteEntries
|
public class AttributeRouteEntries
|
||||||
{
|
{
|
||||||
public List<TreeRouteLinkGenerationEntry> LinkGenerationEntries { get; } = new List<TreeRouteLinkGenerationEntry>();
|
public List<InboundRouteEntry> InboundEntries { get; } = new List<InboundRouteEntry>();
|
||||||
|
|
||||||
public List<TreeRouteMatchingEntry> MatchingEntries { get; } = new List<TreeRouteMatchingEntry>();
|
public List<OutboundRouteEntry> OutboundEntries { get; } = new List<OutboundRouteEntry>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,9 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Text.Encodings.Web;
|
|
||||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||||
using Microsoft.AspNetCore.Mvc.Routing;
|
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
using Microsoft.AspNetCore.Routing.Internal;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Extensions.ObjectPool;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.Internal
|
namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
{
|
{
|
||||||
|
|
@ -33,19 +28,10 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
throw new ArgumentNullException(nameof(services));
|
throw new ArgumentNullException(nameof(services));
|
||||||
}
|
}
|
||||||
|
|
||||||
var actionDescriptorProvider = services.GetRequiredService<IActionDescriptorCollectionProvider>();
|
|
||||||
var inlineConstraintResolver = services.GetRequiredService<IInlineConstraintResolver>();
|
|
||||||
var pool = services.GetRequiredService<ObjectPool<UriBuildingContext>>();
|
|
||||||
var urlEncoder = services.GetRequiredService<UrlEncoder>();
|
|
||||||
var loggerFactory = services.GetRequiredService<ILoggerFactory>();
|
|
||||||
|
|
||||||
return new AttributeRoute(
|
return new AttributeRoute(
|
||||||
target,
|
target,
|
||||||
actionDescriptorProvider,
|
services.GetRequiredService<IActionDescriptorCollectionProvider>(),
|
||||||
inlineConstraintResolver,
|
services);
|
||||||
pool,
|
|
||||||
urlEncoder,
|
|
||||||
loggerFactory);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,12 @@ using Microsoft.AspNetCore.Mvc.Abstractions;
|
||||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||||
using Microsoft.AspNetCore.Mvc.Routing;
|
using Microsoft.AspNetCore.Mvc.Routing;
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
using Microsoft.AspNetCore.Routing.Constraints;
|
|
||||||
using Microsoft.AspNetCore.Routing.Internal;
|
|
||||||
using Microsoft.AspNetCore.Routing.Template;
|
using Microsoft.AspNetCore.Routing.Template;
|
||||||
using Microsoft.AspNetCore.Routing.Tree;
|
using Microsoft.AspNetCore.Routing.Tree;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Logging.Testing;
|
using Microsoft.Extensions.Logging.Testing;
|
||||||
using Microsoft.Extensions.ObjectPool;
|
using Microsoft.Extensions.ObjectPool;
|
||||||
using Microsoft.Extensions.WebEncoders.Testing;
|
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -105,7 +103,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void AttributeRoute_GetEntries_CreatesLinkGenerationEntry()
|
public void AttributeRoute_GetEntries_CreatesOutboundEntry()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var actions = new List<ActionDescriptor>()
|
var actions = new List<ActionDescriptor>()
|
||||||
|
|
@ -130,32 +128,30 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var builder = CreateBuilder();
|
||||||
var actionDescriptorProvider = CreateActionDescriptorProvider(actions);
|
var actionDescriptorProvider = CreateActionDescriptorProvider(actions);
|
||||||
|
|
||||||
var route = CreateRoute(CreateHandler().Object, actionDescriptorProvider.Object);
|
var route = CreateRoute(CreateHandler().Object, actionDescriptorProvider.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var entries = route.GetEntries(actionDescriptorProvider.Object.ActionDescriptors);
|
route.AddEntries(builder, actionDescriptorProvider.Object.ActionDescriptors);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Collection(
|
Assert.Collection(
|
||||||
entries.LinkGenerationEntries,
|
builder.OutboundEntries,
|
||||||
e =>
|
e =>
|
||||||
{
|
{
|
||||||
Assert.NotNull(e.Binder);
|
|
||||||
Assert.Empty(e.Constraints);
|
Assert.Empty(e.Constraints);
|
||||||
Assert.Empty(e.Defaults);
|
Assert.Empty(e.Defaults);
|
||||||
Assert.Equal(RoutePrecedence.ComputeGenerated(e.Template), e.GenerationPrecedence);
|
Assert.Equal(RoutePrecedence.ComputeOutbound(e.RouteTemplate), e.Precedence);
|
||||||
Assert.Equal("BLOG_INDEX", e.Name);
|
Assert.Equal("BLOG_INDEX", e.RouteName);
|
||||||
Assert.Equal(17, e.Order);
|
Assert.Equal(17, e.Order);
|
||||||
Assert.Equal(actions[0].RouteValueDefaults, e.RequiredLinkValues);
|
Assert.Equal(actions[0].RouteValueDefaults.ToArray(), e.RequiredLinkValues.ToArray());
|
||||||
Assert.Equal("1", e.RouteGroup);
|
Assert.Equal("api/Blog/{id}", e.RouteTemplate.TemplateText);
|
||||||
Assert.Equal("api/Blog/{id}", e.Template.TemplateText);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void AttributeRoute_GetEntries_CreatesLinkGenerationEntry_WithConstraint()
|
public void AttributeRoute_GetEntries_CreatesOutboundEntry_WithConstraint()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var actions = new List<ActionDescriptor>()
|
var actions = new List<ActionDescriptor>()
|
||||||
|
|
@ -180,32 +176,30 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var builder = CreateBuilder();
|
||||||
var actionDescriptorProvider = CreateActionDescriptorProvider(actions);
|
var actionDescriptorProvider = CreateActionDescriptorProvider(actions);
|
||||||
|
|
||||||
var route = CreateRoute(CreateHandler().Object, actionDescriptorProvider.Object);
|
var route = CreateRoute(CreateHandler().Object, actionDescriptorProvider.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var entries = route.GetEntries(actionDescriptorProvider.Object.ActionDescriptors);
|
route.AddEntries(builder, actionDescriptorProvider.Object.ActionDescriptors);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Collection(
|
Assert.Collection(
|
||||||
entries.LinkGenerationEntries,
|
builder.OutboundEntries,
|
||||||
e =>
|
e =>
|
||||||
{
|
{
|
||||||
Assert.NotNull(e.Binder);
|
|
||||||
Assert.Single(e.Constraints, kvp => kvp.Key == "id");
|
Assert.Single(e.Constraints, kvp => kvp.Key == "id");
|
||||||
Assert.Empty(e.Defaults);
|
Assert.Empty(e.Defaults);
|
||||||
Assert.Equal(RoutePrecedence.ComputeGenerated(e.Template), e.GenerationPrecedence);
|
Assert.Equal(RoutePrecedence.ComputeOutbound(e.RouteTemplate), e.Precedence);
|
||||||
Assert.Equal("BLOG_INDEX", e.Name);
|
Assert.Equal("BLOG_INDEX", e.RouteName);
|
||||||
Assert.Equal(17, e.Order);
|
Assert.Equal(17, e.Order);
|
||||||
Assert.Equal(actions[0].RouteValueDefaults, e.RequiredLinkValues);
|
Assert.Equal(actions[0].RouteValueDefaults.ToArray(), e.RequiredLinkValues.ToArray());
|
||||||
Assert.Equal("1", e.RouteGroup);
|
Assert.Equal("api/Blog/{id:int}", e.RouteTemplate.TemplateText);
|
||||||
Assert.Equal("api/Blog/{id:int}", e.Template.TemplateText);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void AttributeRoute_GetEntries_CreatesLinkGenerationEntry_WithDefault()
|
public void AttributeRoute_GetEntries_CreatesOutboundEntry_WithDefault()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var actions = new List<ActionDescriptor>()
|
var actions = new List<ActionDescriptor>()
|
||||||
|
|
@ -230,27 +224,25 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var builder = CreateBuilder();
|
||||||
var actionDescriptorProvider = CreateActionDescriptorProvider(actions);
|
var actionDescriptorProvider = CreateActionDescriptorProvider(actions);
|
||||||
|
|
||||||
var route = CreateRoute(CreateHandler().Object, actionDescriptorProvider.Object);
|
var route = CreateRoute(CreateHandler().Object, actionDescriptorProvider.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var entries = route.GetEntries(actionDescriptorProvider.Object.ActionDescriptors);
|
route.AddEntries(builder, actionDescriptorProvider.Object.ActionDescriptors);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Collection(
|
Assert.Collection(
|
||||||
entries.LinkGenerationEntries,
|
builder.OutboundEntries,
|
||||||
e =>
|
e =>
|
||||||
{
|
{
|
||||||
Assert.NotNull(e.Binder);
|
|
||||||
Assert.Empty(e.Constraints);
|
Assert.Empty(e.Constraints);
|
||||||
Assert.Equal(new RouteValueDictionary(new { slug = "hello" }), e.Defaults);
|
Assert.Equal(new RouteValueDictionary(new { slug = "hello" }), e.Defaults);
|
||||||
Assert.Equal(RoutePrecedence.ComputeGenerated(e.Template), e.GenerationPrecedence);
|
Assert.Equal(RoutePrecedence.ComputeOutbound(e.RouteTemplate), e.Precedence);
|
||||||
Assert.Equal("BLOG_INDEX", e.Name);
|
Assert.Equal("BLOG_INDEX", e.RouteName);
|
||||||
Assert.Equal(17, e.Order);
|
Assert.Equal(17, e.Order);
|
||||||
Assert.Equal(actions[0].RouteValueDefaults, e.RequiredLinkValues);
|
Assert.Equal(actions[0].RouteValueDefaults.ToArray(), e.RequiredLinkValues.ToArray());
|
||||||
Assert.Equal("1", e.RouteGroup);
|
Assert.Equal("api/Blog/{*slug=hello}", e.RouteTemplate.TemplateText);
|
||||||
Assert.Equal("api/Blog/{*slug=hello}", e.Template.TemplateText);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -258,7 +250,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
// actions define the same route info. Link generation happens based on the action name + controller
|
// actions define the same route info. Link generation happens based on the action name + controller
|
||||||
// name.
|
// name.
|
||||||
[Fact]
|
[Fact]
|
||||||
public void AttributeRoute_GetEntries_CreatesLinkGenerationEntry_ForEachAction()
|
public void AttributeRoute_GetEntries_CreatesOutboundEntry_ForEachAction()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var actions = new List<ActionDescriptor>()
|
var actions = new List<ActionDescriptor>()
|
||||||
|
|
@ -301,44 +293,40 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var builder = CreateBuilder();
|
||||||
var actionDescriptorProvider = CreateActionDescriptorProvider(actions);
|
var actionDescriptorProvider = CreateActionDescriptorProvider(actions);
|
||||||
|
|
||||||
var route = CreateRoute(CreateHandler().Object, actionDescriptorProvider.Object);
|
var route = CreateRoute(CreateHandler().Object, actionDescriptorProvider.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var entries = route.GetEntries(actionDescriptorProvider.Object.ActionDescriptors);
|
route.AddEntries(builder, actionDescriptorProvider.Object.ActionDescriptors);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Collection(
|
Assert.Collection(
|
||||||
entries.LinkGenerationEntries,
|
builder.OutboundEntries,
|
||||||
e =>
|
e =>
|
||||||
{
|
{
|
||||||
Assert.NotNull(e.Binder);
|
|
||||||
Assert.Empty(e.Constraints);
|
Assert.Empty(e.Constraints);
|
||||||
Assert.Empty(e.Defaults);
|
Assert.Empty(e.Defaults);
|
||||||
Assert.Equal(RoutePrecedence.ComputeGenerated(e.Template), e.GenerationPrecedence);
|
Assert.Equal(RoutePrecedence.ComputeOutbound(e.RouteTemplate), e.Precedence);
|
||||||
Assert.Equal("BLOG_INDEX", e.Name);
|
Assert.Equal("BLOG_INDEX", e.RouteName);
|
||||||
Assert.Equal(17, e.Order);
|
Assert.Equal(17, e.Order);
|
||||||
Assert.Equal(actions[0].RouteValueDefaults, e.RequiredLinkValues);
|
Assert.Equal(actions[0].RouteValueDefaults.ToArray(), e.RequiredLinkValues.ToArray());
|
||||||
Assert.Equal("1", e.RouteGroup);
|
Assert.Equal("api/Blog/{id}", e.RouteTemplate.TemplateText);
|
||||||
Assert.Equal("api/Blog/{id}", e.Template.TemplateText);
|
|
||||||
},
|
},
|
||||||
e =>
|
e =>
|
||||||
{
|
{
|
||||||
Assert.NotNull(e.Binder);
|
|
||||||
Assert.Empty(e.Constraints);
|
Assert.Empty(e.Constraints);
|
||||||
Assert.Empty(e.Defaults);
|
Assert.Empty(e.Defaults);
|
||||||
Assert.Equal(RoutePrecedence.ComputeGenerated(e.Template), e.GenerationPrecedence);
|
Assert.Equal(RoutePrecedence.ComputeOutbound(e.RouteTemplate), e.Precedence);
|
||||||
Assert.Equal("BLOG_INDEX", e.Name);
|
Assert.Equal("BLOG_INDEX", e.RouteName);
|
||||||
Assert.Equal(17, e.Order);
|
Assert.Equal(17, e.Order);
|
||||||
Assert.Equal(actions[1].RouteValueDefaults, e.RequiredLinkValues);
|
Assert.Equal(actions[1].RouteValueDefaults.ToArray(), e.RequiredLinkValues.ToArray());
|
||||||
Assert.Equal("1", e.RouteGroup);
|
Assert.Equal("api/Blog/{id}", e.RouteTemplate.TemplateText);
|
||||||
Assert.Equal("api/Blog/{id}", e.Template.TemplateText);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void AttributeRoute_GetEntries_CreatesMatchingEntry()
|
public void AttributeRoute_GetEntries_CreatesInboundEntry()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var actions = new List<ActionDescriptor>()
|
var actions = new List<ActionDescriptor>()
|
||||||
|
|
@ -363,34 +351,31 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var builder = CreateBuilder();
|
||||||
var actionDescriptorProvider = CreateActionDescriptorProvider(actions);
|
var actionDescriptorProvider = CreateActionDescriptorProvider(actions);
|
||||||
|
var route = CreateRoute(CreateHandler().Object, actionDescriptorProvider.Object);
|
||||||
var handler = CreateHandler().Object;
|
|
||||||
var route = CreateRoute(handler, actionDescriptorProvider.Object);
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var entries = route.GetEntries(actionDescriptorProvider.Object.ActionDescriptors);
|
route.AddEntries(builder, actionDescriptorProvider.Object.ActionDescriptors);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Collection(
|
Assert.Collection(
|
||||||
entries.MatchingEntries,
|
builder.InboundEntries,
|
||||||
e =>
|
e =>
|
||||||
{
|
{
|
||||||
Assert.Empty(e.Constraints);
|
Assert.Empty(e.Constraints);
|
||||||
Assert.Equal(17, e.Order);
|
Assert.Equal(17, e.Order);
|
||||||
Assert.Equal(RoutePrecedence.ComputeMatched(e.RouteTemplate), e.Precedence);
|
Assert.Equal(RoutePrecedence.ComputeInbound(e.RouteTemplate), e.Precedence);
|
||||||
Assert.Equal("BLOG_INDEX", e.RouteName);
|
Assert.Equal("BLOG_INDEX", e.RouteName);
|
||||||
Assert.Equal("api/Blog/{id}", e.RouteTemplate.TemplateText);
|
Assert.Equal("api/Blog/{id}", e.RouteTemplate.TemplateText);
|
||||||
Assert.Same(handler, e.Target);
|
|
||||||
Assert.Collection(
|
Assert.Collection(
|
||||||
e.TemplateMatcher.Defaults.OrderBy(kvp => kvp.Key),
|
e.Defaults.OrderBy(kvp => kvp.Key),
|
||||||
kvp => Assert.Equal(new KeyValuePair<string, object>(TreeRouter.RouteGroupKey, "1"), kvp));
|
kvp => Assert.Equal(new KeyValuePair<string, object>(TreeRouter.RouteGroupKey, "1"), kvp));
|
||||||
Assert.Same(e.RouteTemplate, e.TemplateMatcher.Template);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void AttributeRoute_GetEntries_CreatesMatchingEntry_WithConstraint()
|
public void AttributeRoute_GetEntries_CreatesInboundEntry_WithConstraint()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var actions = new List<ActionDescriptor>()
|
var actions = new List<ActionDescriptor>()
|
||||||
|
|
@ -415,34 +400,31 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var builder = CreateBuilder();
|
||||||
var actionDescriptorProvider = CreateActionDescriptorProvider(actions);
|
var actionDescriptorProvider = CreateActionDescriptorProvider(actions);
|
||||||
|
var route = CreateRoute(CreateHandler().Object, actionDescriptorProvider.Object);
|
||||||
var handler = CreateHandler().Object;
|
|
||||||
var route = CreateRoute(handler, actionDescriptorProvider.Object);
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var entries = route.GetEntries(actionDescriptorProvider.Object.ActionDescriptors);
|
route.AddEntries(builder, actionDescriptorProvider.Object.ActionDescriptors);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Collection(
|
Assert.Collection(
|
||||||
entries.MatchingEntries,
|
builder.InboundEntries,
|
||||||
e =>
|
e =>
|
||||||
{
|
{
|
||||||
Assert.Single(e.Constraints, kvp => kvp.Key == "id");
|
Assert.Single(e.Constraints, kvp => kvp.Key == "id");
|
||||||
Assert.Equal(17, e.Order);
|
Assert.Equal(17, e.Order);
|
||||||
Assert.Equal(RoutePrecedence.ComputeMatched(e.RouteTemplate), e.Precedence);
|
Assert.Equal(RoutePrecedence.ComputeInbound(e.RouteTemplate), e.Precedence);
|
||||||
Assert.Equal("BLOG_INDEX", e.RouteName);
|
Assert.Equal("BLOG_INDEX", e.RouteName);
|
||||||
Assert.Equal("api/Blog/{id:int}", e.RouteTemplate.TemplateText);
|
Assert.Equal("api/Blog/{id:int}", e.RouteTemplate.TemplateText);
|
||||||
Assert.Same(handler, e.Target);
|
|
||||||
Assert.Collection(
|
Assert.Collection(
|
||||||
e.TemplateMatcher.Defaults.OrderBy(kvp => kvp.Key),
|
e.Defaults.OrderBy(kvp => kvp.Key),
|
||||||
kvp => Assert.Equal(new KeyValuePair<string, object>(TreeRouter.RouteGroupKey, "1"), kvp));
|
kvp => Assert.Equal(new KeyValuePair<string, object>(TreeRouter.RouteGroupKey, "1"), kvp));
|
||||||
Assert.Same(e.RouteTemplate, e.TemplateMatcher.Template);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void AttributeRoute_GetEntries_CreatesMatchingEntry_WithDefault()
|
public void AttributeRoute_GetEntries_CreatesInboundEntry_WithDefault()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var actions = new List<ActionDescriptor>()
|
var actions = new List<ActionDescriptor>()
|
||||||
|
|
@ -467,30 +449,27 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var builder = CreateBuilder();
|
||||||
var actionDescriptorProvider = CreateActionDescriptorProvider(actions);
|
var actionDescriptorProvider = CreateActionDescriptorProvider(actions);
|
||||||
|
var route = CreateRoute(CreateHandler().Object, actionDescriptorProvider.Object);
|
||||||
var handler = CreateHandler().Object;
|
|
||||||
var route = CreateRoute(handler, actionDescriptorProvider.Object);
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var entries = route.GetEntries(actionDescriptorProvider.Object.ActionDescriptors);
|
route.AddEntries(builder, actionDescriptorProvider.Object.ActionDescriptors);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Collection(
|
Assert.Collection(
|
||||||
entries.MatchingEntries,
|
builder.InboundEntries,
|
||||||
e =>
|
e =>
|
||||||
{
|
{
|
||||||
Assert.Empty(e.Constraints);
|
Assert.Empty(e.Constraints);
|
||||||
Assert.Equal(17, e.Order);
|
Assert.Equal(17, e.Order);
|
||||||
Assert.Equal(RoutePrecedence.ComputeMatched(e.RouteTemplate), e.Precedence);
|
Assert.Equal(RoutePrecedence.ComputeInbound(e.RouteTemplate), e.Precedence);
|
||||||
Assert.Equal("BLOG_INDEX", e.RouteName);
|
Assert.Equal("BLOG_INDEX", e.RouteName);
|
||||||
Assert.Equal("api/Blog/{*slug=hello}", e.RouteTemplate.TemplateText);
|
Assert.Equal("api/Blog/{*slug=hello}", e.RouteTemplate.TemplateText);
|
||||||
Assert.Same(handler, e.Target);
|
|
||||||
Assert.Collection(
|
Assert.Collection(
|
||||||
e.TemplateMatcher.Defaults.OrderBy(kvp => kvp.Key),
|
e.Defaults.OrderBy(kvp => kvp.Key),
|
||||||
kvp => Assert.Equal(new KeyValuePair<string, object>(TreeRouter.RouteGroupKey, "1"), kvp),
|
kvp => Assert.Equal(new KeyValuePair<string, object>(TreeRouter.RouteGroupKey, "1"), kvp),
|
||||||
kvp => Assert.Equal(new KeyValuePair<string, object>("slug", "hello"), kvp));
|
kvp => Assert.Equal(new KeyValuePair<string, object>("slug", "hello"), kvp));
|
||||||
Assert.Same(e.RouteTemplate, e.TemplateMatcher.Template);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -498,7 +477,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
// actions define the same route info. Link generation happens based on the action name + controller
|
// actions define the same route info. Link generation happens based on the action name + controller
|
||||||
// name.
|
// name.
|
||||||
[Fact]
|
[Fact]
|
||||||
public void AttributeRoute_GetEntries_CreatesMatchingEntry_CombinesLikeActions()
|
public void AttributeRoute_GetEntries_CreatesInboundEntry_CombinesLikeActions()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var actions = new List<ActionDescriptor>()
|
var actions = new List<ActionDescriptor>()
|
||||||
|
|
@ -541,32 +520,41 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var builder = CreateBuilder();
|
||||||
var actionDescriptorProvider = CreateActionDescriptorProvider(actions);
|
var actionDescriptorProvider = CreateActionDescriptorProvider(actions);
|
||||||
|
var route = CreateRoute(CreateHandler().Object, actionDescriptorProvider.Object);
|
||||||
var handler = CreateHandler().Object;
|
|
||||||
var route = CreateRoute(handler, actionDescriptorProvider.Object);
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var entries = route.GetEntries(actionDescriptorProvider.Object.ActionDescriptors);
|
route.AddEntries(builder, actionDescriptorProvider.Object.ActionDescriptors);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Collection(
|
Assert.Collection(
|
||||||
entries.MatchingEntries,
|
builder.InboundEntries,
|
||||||
e =>
|
e =>
|
||||||
{
|
{
|
||||||
Assert.Empty(e.Constraints);
|
Assert.Empty(e.Constraints);
|
||||||
Assert.Equal(17, e.Order);
|
Assert.Equal(17, e.Order);
|
||||||
Assert.Equal(RoutePrecedence.ComputeMatched(e.RouteTemplate), e.Precedence);
|
Assert.Equal(RoutePrecedence.ComputeInbound(e.RouteTemplate), e.Precedence);
|
||||||
Assert.Equal("BLOG_INDEX", e.RouteName);
|
Assert.Equal("BLOG_INDEX", e.RouteName);
|
||||||
Assert.Equal("api/Blog/{id}", e.RouteTemplate.TemplateText);
|
Assert.Equal("api/Blog/{id}", e.RouteTemplate.TemplateText);
|
||||||
Assert.Same(handler, e.Target);
|
|
||||||
Assert.Collection(
|
Assert.Collection(
|
||||||
e.TemplateMatcher.Defaults.OrderBy(kvp => kvp.Key),
|
e.Defaults.OrderBy(kvp => kvp.Key),
|
||||||
kvp => Assert.Equal(new KeyValuePair<string, object>(TreeRouter.RouteGroupKey, "1"), kvp));
|
kvp => Assert.Equal(new KeyValuePair<string, object>(TreeRouter.RouteGroupKey, "1"), kvp));
|
||||||
Assert.Same(e.RouteTemplate, e.TemplateMatcher.Template);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static TreeRouteBuilder CreateBuilder()
|
||||||
|
{
|
||||||
|
var services = new ServiceCollection()
|
||||||
|
.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>()
|
||||||
|
.AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance)
|
||||||
|
.AddLogging()
|
||||||
|
.AddRouting()
|
||||||
|
.AddOptions()
|
||||||
|
.BuildServiceProvider();
|
||||||
|
return services.GetRequiredService<TreeRouteBuilder>();
|
||||||
|
}
|
||||||
|
|
||||||
private static Mock<IRouter> CreateHandler()
|
private static Mock<IRouter> CreateHandler()
|
||||||
{
|
{
|
||||||
var handler = new Mock<IRouter>(MockBehavior.Strict);
|
var handler = new Mock<IRouter>(MockBehavior.Strict);
|
||||||
|
|
@ -593,23 +581,14 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
IRouter handler,
|
IRouter handler,
|
||||||
IActionDescriptorCollectionProvider actionDescriptorProvider)
|
IActionDescriptorCollectionProvider actionDescriptorProvider)
|
||||||
{
|
{
|
||||||
var constraintResolver = new Mock<IInlineConstraintResolver>();
|
var services = new ServiceCollection()
|
||||||
constraintResolver
|
.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>()
|
||||||
.Setup(c => c.ResolveConstraint("int"))
|
.AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance)
|
||||||
.Returns(new IntRouteConstraint());
|
.AddLogging()
|
||||||
|
.AddRouting()
|
||||||
var policy = new UriBuilderContextPooledObjectPolicy(new UrlTestEncoder());
|
.AddOptions()
|
||||||
var pool = new DefaultObjectPool<UriBuildingContext>(policy);
|
.BuildServiceProvider();
|
||||||
|
return new AttributeRoute(handler, actionDescriptorProvider, services);
|
||||||
var route = new AttributeRoute(
|
|
||||||
handler,
|
|
||||||
actionDescriptorProvider,
|
|
||||||
constraintResolver.Object,
|
|
||||||
pool,
|
|
||||||
new UrlTestEncoder(),
|
|
||||||
NullLoggerFactory.Instance);
|
|
||||||
|
|
||||||
return route;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -199,7 +199,10 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>()
|
.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>()
|
||||||
.AddSingleton<UrlEncoder>(new UrlTestEncoder());
|
.AddSingleton<UrlEncoder>(new UrlTestEncoder());
|
||||||
|
|
||||||
|
services.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>();
|
||||||
services.AddRouting();
|
services.AddRouting();
|
||||||
|
services.AddOptions();
|
||||||
|
services.AddLogging();
|
||||||
|
|
||||||
return services.AddSingleton(actionDescriptorProvider.Object)
|
return services.AddSingleton(actionDescriptorProvider.Object)
|
||||||
.AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance)
|
.AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue