diff --git a/src/Microsoft.AspNetCore.Routing/RouteCollection.cs b/src/Microsoft.AspNetCore.Routing/RouteCollection.cs index 1d359cee57..b25748552c 100644 --- a/src/Microsoft.AspNetCore.Routing/RouteCollection.cs +++ b/src/Microsoft.AspNetCore.Routing/RouteCollection.cs @@ -139,7 +139,7 @@ namespace Microsoft.AspNetCore.Routing var url = pathData.VirtualPath; - if (!string.IsNullOrEmpty(url) && (_options.LowercaseUrls || _options.LowercaseQueryStrings || _options.AppendTrailingSlash)) + if (!string.IsNullOrEmpty(url) && (_options.LowercaseUrls || _options.AppendTrailingSlash)) { var indexOfSeparator = url.IndexOfAny(UrlQueryDelimiters); var urlWithoutQueryString = url; @@ -156,7 +156,7 @@ namespace Microsoft.AspNetCore.Routing urlWithoutQueryString = urlWithoutQueryString.ToLowerInvariant(); } - if (_options.LowercaseQueryStrings) + if (_options.LowercaseUrls && _options.LowercaseQueryStrings) { queryString = queryString.ToLowerInvariant(); } diff --git a/src/Microsoft.AspNetCore.Routing/RouteOptions.cs b/src/Microsoft.AspNetCore.Routing/RouteOptions.cs index 45f5589ed0..6cf08bd68a 100644 --- a/src/Microsoft.AspNetCore.Routing/RouteOptions.cs +++ b/src/Microsoft.AspNetCore.Routing/RouteOptions.cs @@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Routing public bool LowercaseUrls { get; set; } /// - /// Gets or sets a value indicating whether all generated QUERY STRINGS are lower-case. + /// Gets or sets a value indicating whether all generated QUERY STRINGS are lower-case. property will when LowercaseUrls true. /// public bool LowercaseQueryStrings { get; set; } diff --git a/test/Microsoft.AspNetCore.Routing.Tests/RouteCollectionTest.cs b/test/Microsoft.AspNetCore.Routing.Tests/RouteCollectionTest.cs index c0d5a0187a..a92bccdfcc 100644 --- a/test/Microsoft.AspNetCore.Routing.Tests/RouteCollectionTest.cs +++ b/test/Microsoft.AspNetCore.Routing.Tests/RouteCollectionTest.cs @@ -89,6 +89,44 @@ namespace Microsoft.AspNetCore.Routing Assert.Empty(pathData.DataTokens); } + [Theory] + [InlineData(@"Home/Index/23?Param1=ABC&Param2=Xyz", "/Home/Index/23?Param1=ABC&Param2=Xyz", false, true, false)] + [InlineData(@"Home/Index/23?Param1=ABC&Param2=Xyz", "/Home/Index/23?Param1=ABC&Param2=Xyz", false, false, false)] + [InlineData(@"Home/Index/23?Param1=ABC&Param2=Xyz", "/home/index/23/?param1=abc¶m2=xyz", true, true, true)] + [InlineData(@"Home/Index/23#Param1=ABC&Param2=Xyz", "/Home/Index/23/#Param1=ABC&Param2=Xyz", false, true, true)] + [InlineData(@"Home/Index/23#Param1=ABC&Param2=Xyz", "/home/index/23#Param1=ABC&Param2=Xyz", true, false, false)] + [InlineData(@"Home/Index/23/?Param1=ABC&Param2=Xyz", "/home/index/23/?param1=abc¶m2=xyz", true, true, true)] + [InlineData(@"Home/Index/23/#Param1=ABC&Param2=Xyz", "/home/index/23/#Param1=ABC&Param2=Xyz", true, false, true)] + [InlineData(@"Home/Index/23/#Param1=ABC&Param2=Xyz", "/home/index/23/#param1=abc¶m2=xyz", true, true, true)] + public void GetVirtualPath_CanLowerCaseUrls_QueryStrings_BasedOnOptions( + string returnUrl, + string expectedUrl, + bool lowercaseUrls, + bool lowercaseQueryStrings, bool appendTrailingSlash) + { + // Arrange + var target = new Mock(MockBehavior.Strict); + target + .Setup(e => e.GetVirtualPath(It.IsAny())) + .Returns(new VirtualPathData(target.Object, returnUrl)); + + var routeCollection = new RouteCollection(); + routeCollection.Add(target.Object); + var virtualPathContext = CreateVirtualPathContext( + options: GetRouteOptions( + lowerCaseUrls: lowercaseUrls, + lowercaseQueryStrings: lowercaseQueryStrings, + appendTrailingSlash: appendTrailingSlash)); + + // Act + var pathData = routeCollection.GetVirtualPath(virtualPathContext); + + // Assert + Assert.Equal(expectedUrl, pathData.VirtualPath); + Assert.Same(target.Object, pathData.Router); + Assert.Empty(pathData.DataTokens); + } + [Theory] [MemberData(nameof(DataTokensTestData))] public void GetVirtualPath_ReturnsDataTokens(RouteValueDictionary dataTokens, string routerName) @@ -663,12 +701,13 @@ namespace Microsoft.AspNetCore.Routing private static Action GetRouteOptions( bool lowerCaseUrls = false, - bool appendTrailingSlash = false) + bool appendTrailingSlash = false, bool lowercaseQueryStrings = false) { return (options) => { options.LowercaseUrls = lowerCaseUrls; options.AppendTrailingSlash = appendTrailingSlash; + options.LowercaseQueryStrings = lowercaseQueryStrings; }; } }