diff --git a/src/Microsoft.AspNetCore.Routing/Matchers/DefaultMatchProcessorFactory.cs b/src/Microsoft.AspNetCore.Routing/Matchers/DefaultMatchProcessorFactory.cs index 5226683626..f4acb68f78 100644 --- a/src/Microsoft.AspNetCore.Routing/Matchers/DefaultMatchProcessorFactory.cs +++ b/src/Microsoft.AspNetCore.Routing/Matchers/DefaultMatchProcessorFactory.cs @@ -3,7 +3,6 @@ using System; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; namespace Microsoft.AspNetCore.Routing.Matchers @@ -11,16 +10,13 @@ namespace Microsoft.AspNetCore.Routing.Matchers internal class DefaultMatchProcessorFactory : MatchProcessorFactory { private readonly RouteOptions _options; - private readonly ILogger _logger; private readonly IServiceProvider _serviceProvider; public DefaultMatchProcessorFactory( IOptions options, - ILogger logger, IServiceProvider serviceProvider) { _options = options.Value; - _logger = logger; _serviceProvider = serviceProvider; } @@ -67,13 +63,16 @@ namespace Microsoft.AspNetCore.Routing.Matchers { throw new InvalidOperationException( Resources.FormatDefaultInlineConstraintResolver_TypeNotConstraint( - constraintType, constraintName, typeof(IRouteConstraint).Name)); + constraintType, + constraintName, + typeof(IRouteConstraint).Name)); } try { return CreateMatchProcessorFromRouteConstraint( matchProcessorReference.ParameterName, + matchProcessorReference.Optional, constraintType, constraintArgument); } @@ -91,11 +90,20 @@ namespace Microsoft.AspNetCore.Routing.Matchers private MatchProcessor CreateMatchProcessorFromRouteConstraint( string parameterName, + bool optional, Type constraintType, string constraintArgument) { var routeConstraint = DefaultInlineConstraintResolver.CreateConstraint(constraintType, constraintArgument); - return (new MatchProcessorReference(parameterName, routeConstraint)).MatchProcessor; + var matchProcessor = new MatchProcessorReference(parameterName, routeConstraint).MatchProcessor; + if (optional) + { + matchProcessor = new OptionalMatchProcessor(matchProcessor); + } + + matchProcessor.Initialize(parameterName, constraintArgument); + + return matchProcessor; } private MatchProcessor ResolveMatchProcessor( diff --git a/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGeneratorTest.cs b/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGeneratorTest.cs index db93c930c5..d73352a9c5 100644 --- a/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGeneratorTest.cs +++ b/test/Microsoft.AspNetCore.Routing.Tests/DefaultLinkGeneratorTest.cs @@ -801,7 +801,6 @@ namespace Microsoft.AspNetCore.Routing return new DefaultLinkGenerator( new DefaultMatchProcessorFactory( Options.Create(new RouteOptions()), - NullLogger.Instance, Mock.Of()), new DefaultObjectPool(new UriBuilderContextPooledObjectPolicy()), NullLogger.Instance); diff --git a/test/Microsoft.AspNetCore.Routing.Tests/Matchers/BarebonesMatcher.cs b/test/Microsoft.AspNetCore.Routing.Tests/Matchers/BarebonesMatcher.cs index 68a6763606..d70cd6eece 100644 --- a/test/Microsoft.AspNetCore.Routing.Tests/Matchers/BarebonesMatcher.cs +++ b/test/Microsoft.AspNetCore.Routing.Tests/Matchers/BarebonesMatcher.cs @@ -31,9 +31,10 @@ namespace Microsoft.AspNetCore.Routing.Matchers throw new ArgumentNullException(nameof(feature)); } + var path = httpContext.Request.Path.Value; for (var i = 0; i < Matchers.Length; i++) { - if (Matchers[i].TryMatch(httpContext.Request.Path.Value)) + if (Matchers[i].TryMatch(path)) { feature.Endpoint = Matchers[i].Endpoint; feature.Values = new RouteValueDictionary(); diff --git a/test/Microsoft.AspNetCore.Routing.Tests/Matchers/DefaultMatchProcessorFactoryTest.cs b/test/Microsoft.AspNetCore.Routing.Tests/Matchers/DefaultMatchProcessorFactoryTest.cs index 1f89aa1928..5207607531 100644 --- a/test/Microsoft.AspNetCore.Routing.Tests/Matchers/DefaultMatchProcessorFactoryTest.cs +++ b/test/Microsoft.AspNetCore.Routing.Tests/Matchers/DefaultMatchProcessorFactoryTest.cs @@ -56,6 +56,20 @@ namespace Microsoft.AspNetCore.Routing.Matchers Assert.False(isMatch); } + [Fact] + public void Create_CreatesMatchProcessor_FromConstraintText_AndRouteConstraint_Optional() + { + // Arrange + var factory = GetMatchProcessorFactory(); + var matchProcessorReference = new MatchProcessorReference("id", true, "int"); + + // Act + var processor = factory.Create(matchProcessorReference); + + // Assert + Assert.IsType(processor); + } + [Fact] public void Create_CreatesMatchProcessor_FromConstraintText_AndCustomMatchProcessor() { @@ -143,7 +157,6 @@ namespace Microsoft.AspNetCore.Routing.Matchers return new DefaultMatchProcessorFactory( Options.Create(options), - NullLogger.Instance, services.BuildServiceProvider()); } diff --git a/test/Microsoft.AspNetCore.Routing.Tests/Matchers/TreeMatcherTests.cs b/test/Microsoft.AspNetCore.Routing.Tests/Matchers/TreeMatcherTests.cs index e32d4aed76..30639f9e57 100644 --- a/test/Microsoft.AspNetCore.Routing.Tests/Matchers/TreeMatcherTests.cs +++ b/test/Microsoft.AspNetCore.Routing.Tests/Matchers/TreeMatcherTests.cs @@ -33,7 +33,6 @@ namespace Microsoft.AspNetCore.Routing.Matchers var compositeDataSource = new CompositeEndpointDataSource(new[] { endpointDataSource }); var defaultInlineConstraintResolver = new DefaultMatchProcessorFactory( Options.Create(new RouteOptions()), - NullLogger.Instance, Mock.Of()); var endpointSelector = new EndpointSelector( compositeDataSource,