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;
};
}
}