diff --git a/src/Microsoft.AspNetCore.Routing/Internal/LinkGenerationDecisionTree.cs b/src/Microsoft.AspNetCore.Routing/Internal/LinkGenerationDecisionTree.cs index eb055f7696..6242198a46 100644 --- a/src/Microsoft.AspNetCore.Routing/Internal/LinkGenerationDecisionTree.cs +++ b/src/Microsoft.AspNetCore.Routing/Internal/LinkGenerationDecisionTree.cs @@ -15,6 +15,11 @@ namespace Microsoft.AspNetCore.Routing.Internal [DebuggerDisplay("{DebuggerDisplayString,nq}")] public class LinkGenerationDecisionTree { + // Fallback value for cases where the ambient values weren't provided. + // + // This is safe because we don't mutate the route values in here. + private static readonly RouteValueDictionary EmptyAmbientValues = new RouteValueDictionary(); + private readonly DecisionTreeNode _root; public LinkGenerationDecisionTree(IReadOnlyList entries) @@ -30,7 +35,7 @@ namespace Microsoft.AspNetCore.Routing.Internal if (_root.Matches.Count > 0 || _root.Criteria.Count > 0) { var results = new List(); - Walk(results, values, ambientValues, _root, isFallbackPath: false); + Walk(results, values, ambientValues ?? EmptyAmbientValues, _root, isFallbackPath: false); results.Sort(OutboundMatchResultComparer.Instance); return results; } diff --git a/test/Microsoft.AspNetCore.Routing.Tests/Internal/LinkGenerationDecisionTreeTest.cs b/test/Microsoft.AspNetCore.Routing.Tests/Internal/LinkGenerationDecisionTreeTest.cs index f07296faba..94568c2cd8 100644 --- a/test/Microsoft.AspNetCore.Routing.Tests/Internal/LinkGenerationDecisionTreeTest.cs +++ b/test/Microsoft.AspNetCore.Routing.Tests/Internal/LinkGenerationDecisionTreeTest.cs @@ -14,6 +14,26 @@ namespace Microsoft.AspNetCore.Routing.Internal.Routing { public class LinkGenerationDecisionTreeTest { + [Fact] + public void GetMatches_AllowsNullAmbientValues() + { + // Arrange + var entries = new List(); + + var entry = CreateMatch(new { }); + entries.Add(entry); + + var tree = new LinkGenerationDecisionTree(entries); + + var context = CreateContext(new { }); + + // Act + var matches = tree.GetMatches(context.Values, ambientValues: null); + + // Assert + Assert.Same(entry, Assert.Single(matches).Match); + } + [Fact] public void SelectSingleEntry_NoCriteria() {