diff --git a/src/Microsoft.AspNetCore.Routing/Constraints/StringRouteConstraint.cs b/src/Microsoft.AspNetCore.Routing/Constraints/StringRouteConstraint.cs
new file mode 100644
index 0000000000..e7d92ef13c
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Routing/Constraints/StringRouteConstraint.cs
@@ -0,0 +1,67 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Globalization;
+using Microsoft.AspNetCore.Http;
+
+namespace Microsoft.AspNetCore.Routing.Constraints
+{
+ ///
+ /// Constrains a route parameter to contain only a specified strign.
+ ///
+ public class StringRouteConstraint : IRouteConstraint
+ {
+ private string _value;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The constraint value to match.
+ public StringRouteConstraint(string value)
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value));
+ }
+
+ _value = value;
+ }
+
+ ///
+ public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
+ {
+ if (httpContext == null)
+ {
+ throw new ArgumentNullException(nameof(httpContext));
+ }
+
+ if (route == null)
+ {
+ throw new ArgumentNullException(nameof(route));
+ }
+
+ if (routeKey == null)
+ {
+ throw new ArgumentNullException(nameof(routeKey));
+ }
+
+ if (values == null)
+ {
+ throw new ArgumentNullException(nameof(values));
+ }
+
+ object routeValue;
+
+ if (values.TryGetValue(routeKey, out routeValue)
+ && routeValue != null)
+ {
+ var parameterValueString = Convert.ToString(routeValue, CultureInfo.InvariantCulture);
+
+ return parameterValueString.Equals(_value, StringComparison.OrdinalIgnoreCase);
+ }
+
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.AspNetCore.Routing.Tests/Constraints/StringRouteConstraintTest.cs b/test/Microsoft.AspNetCore.Routing.Tests/Constraints/StringRouteConstraintTest.cs
new file mode 100644
index 0000000000..006ce0d382
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Routing.Tests/Constraints/StringRouteConstraintTest.cs
@@ -0,0 +1,157 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Routing.Constraints;
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Routing.Constraints
+{
+ public class StringRouteConstraintTest
+ {
+ [Fact]
+ public void StringRouteConstraintSimpleTrueWithRouteDirectionIncomingRequestTest()
+ {
+ // Arrange
+ var constraint = new StringRouteConstraint("home");
+
+ // Act
+ var values = new RouteValueDictionary(new { controller = "home" });
+
+ var match = constraint.Match(
+ httpContext: Mock.Of(),
+ route: new Mock().Object,
+ routeKey: "controller",
+ values: values,
+ routeDirection: RouteDirection.IncomingRequest);
+
+ // Assert
+ Assert.True(match);
+ }
+
+ [Fact]
+ public void StringRouteConstraintSimpleTrueWithRouteDirectionUrlGenerationTest()
+ {
+ // Arrange
+ var constraint = new StringRouteConstraint("home");
+
+ // Act
+ var values = new RouteValueDictionary(new { controller = "home" });
+
+ var match = constraint.Match(
+ httpContext: Mock.Of(),
+ route: new Mock().Object,
+ routeKey: "controller",
+ values: values,
+ routeDirection: RouteDirection.UrlGeneration);
+
+ // Assert
+ Assert.True(match);
+ }
+
+ [Fact]
+ public void StringRouteConstraintSimpleFalseWithRouteDirectionIncomingRequestTest()
+ {
+ // Arrange
+ var constraint = new StringRouteConstraint("admin");
+
+ // Act
+ var values = new RouteValueDictionary(new { controller = "home" });
+
+ var match = constraint.Match(
+ httpContext: Mock.Of(),
+ route: new Mock().Object,
+ routeKey: "controller",
+ values: values,
+ routeDirection: RouteDirection.IncomingRequest);
+
+ // Assert
+ Assert.False(match);
+ }
+
+ [Fact]
+ public void StringRouteConstraintSimpleFalseWithRouteDirectionUrlGenerationTest()
+ {
+ // Arrange
+ var constraint = new StringRouteConstraint("admin");
+
+ // Act
+ var values = new RouteValueDictionary(new { controller = "home" });
+
+ var match = constraint.Match(
+ httpContext: Mock.Of(),
+ route: new Mock().Object,
+ routeKey: "controller",
+ values: values,
+ routeDirection: RouteDirection.UrlGeneration);
+
+ // Assert
+ Assert.False(match);
+ }
+
+ [Fact]
+ public void StringRouteConstraintKeyNotFoundWithRouteDirectionIncomingRequestTest()
+ {
+ // Arrange
+ var constraint = new StringRouteConstraint("admin");
+
+ // Act
+ var values = new RouteValueDictionary(new { controller = "admin" });
+
+ var match = constraint.Match(
+ httpContext: Mock.Of(),
+ route: new Mock().Object,
+ routeKey: "action",
+ values: values,
+ routeDirection: RouteDirection.IncomingRequest);
+
+ // Assert
+ Assert.False(match);
+ }
+
+ [Fact]
+ public void StringRouteConstraintKeyNotFoundWithRouteDirectionUrlGenerationTest()
+ {
+ // Arrange
+ var constraint = new StringRouteConstraint("admin");
+
+ // Act
+ var values = new RouteValueDictionary(new { controller = "admin" });
+
+ var match = constraint.Match(
+ httpContext: Mock.Of(),
+ route: new Mock().Object,
+ routeKey: "action",
+ values: values,
+ routeDirection: RouteDirection.UrlGeneration);
+
+ // Assert
+ Assert.False(match);
+ }
+
+ [Theory]
+ [InlineData("User", "uSer", true)]
+ [InlineData("User.Admin", "User.Admin", true)]
+ [InlineData(@"User\Admin", "User\\Admin", true)]
+ [InlineData(null, "user", false)]
+ public void StringRouteConstraintEscapingCaseSensitiveAndRouteNullTest(string routeValue, string constraintValue, bool expected)
+ {
+ // Arrange
+ var constraint = new StringRouteConstraint(constraintValue);
+
+ // Act
+ var values = new RouteValueDictionary(new { controller = routeValue });
+
+ var match = constraint.Match(
+ httpContext: Mock.Of(),
+ route: new Mock().Object,
+ routeKey: "controller",
+ values: values,
+ routeDirection: RouteDirection.IncomingRequest);
+
+ // Assert
+ Assert.Equal(expected, match);
+ }
+ }
+}
\ No newline at end of file