diff --git a/src/Microsoft.AspNetCore.Routing/Internal/UriBuildingContext.cs b/src/Microsoft.AspNetCore.Routing/Internal/UriBuildingContext.cs index 1f61db30b2..82e0b4137b 100644 --- a/src/Microsoft.AspNetCore.Routing/Internal/UriBuildingContext.cs +++ b/src/Microsoft.AspNetCore.Routing/Internal/UriBuildingContext.cs @@ -242,18 +242,29 @@ namespace Microsoft.AspNetCore.Routing.Internal // Used by TemplateBinder.TryBindValues - the new code path of LinkGenerator public PathString ToPathString() { - if (_path.Length > 0 && _path[0] != '/') + PathString pathString; + + if (_path.Length > 0) { - // Normalize generated paths so that they always contain a leading slash. - _path.Insert(0, '/'); + if (_path[0] != '/') + { + // Normalize generated paths so that they always contain a leading slash. + _path.Insert(0, '/'); + } + + if (AppendTrailingSlash && _path[_path.Length - 1] != '/') + { + _path.Append('/'); + } + + pathString = new PathString(_path.ToString()); + } + else + { + pathString = PathString.Empty; } - if (AppendTrailingSlash && _path.Length > 0 && _path[_path.Length - 1] != '/') - { - _path.Append('/'); - } - - return new PathString(_path.ToString()); + return pathString; } // Used by TemplateBinder.TryBindValues - the new code path of LinkGenerator diff --git a/test/Microsoft.AspNetCore.Routing.Tests/Internal/UriBuildingContextTest.cs b/test/Microsoft.AspNetCore.Routing.Tests/Internal/UriBuildingContextTest.cs index 137520051c..cfd1531a5d 100644 --- a/test/Microsoft.AspNetCore.Routing.Tests/Internal/UriBuildingContextTest.cs +++ b/test/Microsoft.AspNetCore.Routing.Tests/Internal/UriBuildingContextTest.cs @@ -65,5 +65,36 @@ namespace Microsoft.AspNetCore.Routing.Internal // Assert Assert.Equal(expected, uriBuilldingContext.ToString()); } + + [Theory] + [InlineData("/Author", false, false, "/UrlEncode[[Author]]")] + [InlineData("/Author", false, true, "/UrlEncode[[Author]]")] + [InlineData("/Author", true, false, "/UrlEncode[[Author]]/")] + [InlineData("/Author", true, true, "/UrlEncode[[Author]]/")] + [InlineData("/Author/", false, false, "/UrlEncode[[Author]]/")] + [InlineData("/Author/", false, true, "/UrlEncode[[Author/]]")] + [InlineData("/Author/", true, false, "/UrlEncode[[Author]]/")] + [InlineData("/Author/", true, true, "/UrlEncode[[Author/]]/")] + [InlineData("Author", false, false, "/UrlEncode[[Author]]")] + [InlineData("Author", false, true, "/UrlEncode[[Author]]")] + [InlineData("Author", true, false, "/UrlEncode[[Author]]/")] + [InlineData("Author", true, true, "/UrlEncode[[Author]]/")] + [InlineData("", false, false, "")] + [InlineData("", false, true, "")] + [InlineData("", true, false, "")] + [InlineData("", true, true, "")] + public void ToPathString(string url, bool appendTrailingSlash, bool encodeSlashes, string expected) + { + // Arrange + var urlTestEncoder = new UrlTestEncoder(); + var uriBuilldingContext = new UriBuildingContext(urlTestEncoder); + uriBuilldingContext.AppendTrailingSlash = appendTrailingSlash; + + // Act + uriBuilldingContext.Accept(url, encodeSlashes); + + // Assert + Assert.Equal(expected, uriBuilldingContext.ToPathString().Value); + } } }