diff --git a/src/Microsoft.AspNet.Routing/Constraints/RegexInlineRouteConstraint.cs b/src/Microsoft.AspNet.Routing/Constraints/RegexInlineRouteConstraint.cs
new file mode 100644
index 0000000000..be035af694
--- /dev/null
+++ b/src/Microsoft.AspNet.Routing/Constraints/RegexInlineRouteConstraint.cs
@@ -0,0 +1,20 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+namespace Microsoft.AspNet.Routing.Constraints
+{
+ ///
+ /// Represents a regex constraint which can be used as an inlineConstraint.
+ ///
+ public class RegexInlineRouteConstraint : RegexRouteConstraint
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The regular expression pattern to match.
+ public RegexInlineRouteConstraint([NotNull] string regexPattern)
+ : base(regexPattern)
+ {
+ }
+ }
+}
diff --git a/src/Microsoft.AspNet.Routing/Microsoft.AspNet.Routing.kproj b/src/Microsoft.AspNet.Routing/Microsoft.AspNet.Routing.kproj
index b3983b08bb..ce9c337704 100644
--- a/src/Microsoft.AspNet.Routing/Microsoft.AspNet.Routing.kproj
+++ b/src/Microsoft.AspNet.Routing/Microsoft.AspNet.Routing.kproj
@@ -16,5 +16,6 @@
2.0
+
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Routing/RouteOptions.cs b/src/Microsoft.AspNet.Routing/RouteOptions.cs
index 227f4d74aa..96c78c992f 100644
--- a/src/Microsoft.AspNet.Routing/RouteOptions.cs
+++ b/src/Microsoft.AspNet.Routing/RouteOptions.cs
@@ -56,6 +56,7 @@ namespace Microsoft.AspNet.Routing
// Regex-based constraints
{ "alpha", typeof(AlphaRouteConstraint) },
+ { "regex", typeof(RegexInlineRouteConstraint) },
};
}
}
diff --git a/test/Microsoft.AspNet.Routing.Tests/Constraints/RegexInlineRouteConstraintTests.cs b/test/Microsoft.AspNet.Routing.Tests/Constraints/RegexInlineRouteConstraintTests.cs
new file mode 100644
index 0000000000..39c36c4faf
--- /dev/null
+++ b/test/Microsoft.AspNet.Routing.Tests/Constraints/RegexInlineRouteConstraintTests.cs
@@ -0,0 +1,91 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+#if NET45
+
+using System.Globalization;
+using System.Threading;
+using Microsoft.AspNet.Http;
+using Microsoft.AspNet.Routing.Constraints;
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNet.Routing.Tests
+{
+ public class RegexInlineRouteConstraintTests
+ {
+ [Theory]
+ [InlineData("abc", "abc", true)] // simple match
+ [InlineData("Abc", "abc", true)] // case insensitive match
+ [InlineData("Abc ", "abc", true)] // Extra space on input match (because we don't add ^({0})$
+ [InlineData("Abcd", "abc", true)] // Extra char
+ [InlineData("^Abcd", "abc", true)] // Extra special char
+ [InlineData("Abc", " abc", false)] // Missing char
+ public void RegexInlineConstraintBuildRegexVerbatimFromInput(string routeValue,
+ string constraintValue,
+ bool shouldMatch)
+ {
+ // Arrange
+ var constraint = new RegexInlineRouteConstraint(constraintValue);
+ var values = new RouteValueDictionary(new {controller = routeValue});
+
+ // Assert
+ Assert.Equal(shouldMatch, EasyMatch(constraint, "controller", values));
+ }
+
+ [Fact]
+ public void RegexInlineConstraint_FailsIfKeyIsNotFoundInRouteValues()
+ {
+ // Arrange
+ var constraint = new RegexInlineRouteConstraint("^abc$");
+ var values = new RouteValueDictionary(new { action = "abc" });
+
+ // Assert
+ Assert.False(EasyMatch(constraint, "controller", values));
+ }
+
+ [Fact]
+ public void RegexInlineConstraint_IsCultureInsensitive()
+ {
+ // Arrange
+ var constraint = new RegexInlineRouteConstraint("^([a-z]+)$");
+ var values = new RouteValueDictionary(new { controller = "\u0130" }); // Turkish upper-case dotted I
+
+ var currentThread = Thread.CurrentThread;
+ var backupCulture = currentThread.CurrentCulture;
+
+ bool matchInTurkish;
+ bool matchInUsEnglish;
+
+ // Act
+ try
+ {
+ currentThread.CurrentCulture = new CultureInfo("tr-TR"); // Turkish culture
+ matchInTurkish = EasyMatch(constraint, "controller", values);
+
+ currentThread.CurrentCulture = new CultureInfo("en-US");
+ matchInUsEnglish = EasyMatch(constraint, "controller", values);
+ }
+ finally
+ {
+ currentThread.CurrentCulture = backupCulture;
+ }
+
+ // Assert
+ Assert.False(matchInUsEnglish); // this just verifies the test
+ Assert.False(matchInTurkish);
+ }
+
+ private static bool EasyMatch(IRouteConstraint constraint,
+ string routeKey,
+ RouteValueDictionary values)
+ {
+ return constraint.Match(httpContext: new Mock().Object,
+ route: new Mock().Object,
+ routeKey: routeKey,
+ values: values,
+ routeDirection: RouteDirection.IncomingRequest);
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Routing.Tests/Constraints/RegexConstraintTests.cs b/test/Microsoft.AspNet.Routing.Tests/Constraints/RegexRouteConstraintTests.cs
similarity index 98%
rename from test/Microsoft.AspNet.Routing.Tests/Constraints/RegexConstraintTests.cs
rename to test/Microsoft.AspNet.Routing.Tests/Constraints/RegexRouteConstraintTests.cs
index 0c67824e03..7aa8e91377 100644
--- a/test/Microsoft.AspNet.Routing.Tests/Constraints/RegexConstraintTests.cs
+++ b/test/Microsoft.AspNet.Routing.Tests/Constraints/RegexRouteConstraintTests.cs
@@ -13,7 +13,7 @@ using Xunit;
namespace Microsoft.AspNet.Routing.Tests
{
- public class RegexConstraintTests
+ public class RegexRouteConstraintTests
{
[Theory]
[InlineData("abc", "abc", true)] // simple match
diff --git a/test/Microsoft.AspNet.Routing.Tests/DefaultInlineConstraintResolverTest.cs b/test/Microsoft.AspNet.Routing.Tests/DefaultInlineConstraintResolverTest.cs
index 07195cbd99..b9908954e1 100644
--- a/test/Microsoft.AspNet.Routing.Tests/DefaultInlineConstraintResolverTest.cs
+++ b/test/Microsoft.AspNet.Routing.Tests/DefaultInlineConstraintResolverTest.cs
@@ -42,6 +42,7 @@ namespace Microsoft.AspNet.Routing.Tests
" with the following number of parameters: 1.",
ex.Message);
}
+
[Fact]
public void ResolveConstraint_AlphaConstraint()
{
@@ -52,6 +53,16 @@ namespace Microsoft.AspNet.Routing.Tests
Assert.IsType(constraint);
}
+ [Fact]
+ public void ResolveConstraint_RegexInlineConstraint_WithAComma_PassesAsASingleArgument()
+ {
+ // Arrange & Act
+ var constraint = _constraintResolver.ResolveConstraint("regex(ab,1)");
+
+ // Assert
+ Assert.IsType(constraint);
+ }
+
[Fact]
public void ResolveConstraint_BoolConstraint()
{
diff --git a/test/Microsoft.AspNet.Routing.Tests/Microsoft.AspNet.Routing.Tests.kproj b/test/Microsoft.AspNet.Routing.Tests/Microsoft.AspNet.Routing.Tests.kproj
index 4514503b19..323a4b4b09 100644
--- a/test/Microsoft.AspNet.Routing.Tests/Microsoft.AspNet.Routing.Tests.kproj
+++ b/test/Microsoft.AspNet.Routing.Tests/Microsoft.AspNet.Routing.Tests.kproj
@@ -16,5 +16,6 @@
2.0
+
\ No newline at end of file