diff --git a/src/Microsoft.AspNet.Routing/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Routing/Properties/Resources.Designer.cs index 10d5e4bcaa..d5bad451a4 100644 --- a/src/Microsoft.AspNet.Routing/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Routing/Properties/Resources.Designer.cs @@ -299,7 +299,7 @@ namespace Microsoft.AspNet.Routing } /// - /// The route parameter name '{0}' is invalid. Route parameter names must be non-empty and cannot contain these characters: '{{', '}}', '/'. The '?' character marks a parameter as optional, and can only occur at the end of the parameter. + /// The route parameter name '{0}' is invalid. Route parameter names must be non-empty and cannot contain these characters: '{{', '}}', '/'. The '?' character marks a parameter as optional, and can occur only at the end of the parameter. The '*' character marks a parameter as catch-all, and can occur only at the start of the parameter. /// internal static string TemplateRoute_InvalidParameterName { @@ -307,7 +307,7 @@ namespace Microsoft.AspNet.Routing } /// - /// The route parameter name '{0}' is invalid. Route parameter names must be non-empty and cannot contain these characters: '{{', '}}', '/'. The '?' character marks a parameter as optional, and can only occur at the end of the parameter. + /// The route parameter name '{0}' is invalid. Route parameter names must be non-empty and cannot contain these characters: '{{', '}}', '/'. The '?' character marks a parameter as optional, and can occur only at the end of the parameter. The '*' character marks a parameter as catch-all, and can occur only at the start of the parameter. /// internal static string FormatTemplateRoute_InvalidParameterName(object p0) { diff --git a/src/Microsoft.AspNet.Routing/Resources.resx b/src/Microsoft.AspNet.Routing/Resources.resx index 364a133d65..7c5e990d81 100644 --- a/src/Microsoft.AspNet.Routing/Resources.resx +++ b/src/Microsoft.AspNet.Routing/Resources.resx @@ -172,7 +172,7 @@ The literal section '{0}' is invalid. Literal sections cannot contain the '?' character. - The route parameter name '{0}' is invalid. Route parameter names must be non-empty and cannot contain these characters: '{{', '}}', '/'. The '?' character marks a parameter as optional, and can only occur at the end of the parameter. + The route parameter name '{0}' is invalid. Route parameter names must be non-empty and cannot contain these characters: '{{', '}}', '/'. The '?' character marks a parameter as optional, and can occur only at the end of the parameter. The '*' character marks a parameter as catch-all, and can occur only at the start of the parameter. The route template cannot start with a '/' or '~' character. diff --git a/src/Microsoft.AspNet.Routing/Template/TemplateParser.cs b/src/Microsoft.AspNet.Routing/Template/TemplateParser.cs index 813b9d545a..48482902df 100644 --- a/src/Microsoft.AspNet.Routing/Template/TemplateParser.cs +++ b/src/Microsoft.AspNet.Routing/Template/TemplateParser.cs @@ -15,7 +15,8 @@ namespace Microsoft.AspNet.Routing.Template private const char CloseBrace = '}'; private const char EqualsSign = '='; private const char QuestionMark = '?'; - + private const char Asterisk = '*'; + public static RouteTemplate Parse(string routeTemplate, IInlineConstraintResolver constraintResolver) { if (routeTemplate == null) @@ -358,7 +359,7 @@ namespace Microsoft.AspNet.Routing.Template for (var i = 0; i < parameterName.Length; i++) { var c = parameterName[i]; - if (c == Separator || c == OpenBrace || c == CloseBrace || c == QuestionMark) + if (c == Separator || c == OpenBrace || c == CloseBrace || c == QuestionMark || c == Asterisk) { context.Error = String.Format(CultureInfo.CurrentCulture, Resources.TemplateRoute_InvalidParameterName, parameterName); diff --git a/test/Microsoft.AspNet.Routing.Tests/Template/TemplateParserTests.cs b/test/Microsoft.AspNet.Routing.Tests/Template/TemplateParserTests.cs index 815cfd5132..175b49e32b 100644 --- a/test/Microsoft.AspNet.Routing.Tests/Template/TemplateParserTests.cs +++ b/test/Microsoft.AspNet.Routing.Tests/Template/TemplateParserTests.cs @@ -284,8 +284,31 @@ namespace Microsoft.AspNet.Routing.Template.Tests { ExceptionAssert.Throws( () => TemplateParser.Parse("foo/{*}", _inlineConstraintResolver), - "The route parameter name '' is invalid. Route parameter names must be non-empty and cannot contain these characters: '{', '}', '/'. " + - "The '?' character marks a parameter as optional, and can only occur at the end of the parameter." + Environment.NewLine + + "The route parameter name '' is invalid. Route parameter names must be non-empty and cannot" + + " contain these characters: '{', '}', '/'. The '?' character marks a parameter as optional," + + " and can occur only at the end of the parameter. The '*' character marks a parameter as catch-all," + + " and can occur only at the start of the parameter." + Environment.NewLine + + "Parameter name: routeTemplate"); + } + + [Theory] + [InlineData("{**}", "*")] + [InlineData("{a*}", "a*")] + [InlineData("{*a*}", "a*")] + [InlineData("{*a*:int}", "a*")] + [InlineData("{*a*=5}", "a*")] + [InlineData("{*a*b=5}", "a*b")] + public void ParseRouteParameter_ThrowsIf_ParameterContainsAsterisk(string template, string parameterName) + { + // Arrange + var expectedMessage = "The route parameter name '" + parameterName + "' is invalid. Route parameter " + + "names must be non-empty and cannot contain these characters: '{', '}', '/'. The '?' character " + + "marks a parameter as optional, and can occur only at the end of the parameter. The '*' character " + + "marks a parameter as catch-all, and can occur only at the start of the parameter."; + + // Act & Assert + ExceptionAssert.Throws( + () => TemplateParser.Parse(template, _inlineConstraintResolver), expectedMessage + Environment.NewLine + "Parameter name: routeTemplate"); } @@ -339,8 +362,10 @@ namespace Microsoft.AspNet.Routing.Template.Tests { ExceptionAssert.Throws( () => TemplateParser.Parse("{a}/{a{aa}/{z}", _inlineConstraintResolver), - "The route parameter name 'a{aa' is invalid. Route parameter names must be non-empty and cannot contain these characters: '{', '}', '/'. " + - "The '?' character marks a parameter as optional, and can only occur at the end of the parameter." + Environment.NewLine + + "The route parameter name 'a{aa' is invalid. Route parameter names must be non-empty and cannot" + + " contain these characters: '{', '}', '/'. The '?' character marks a parameter as optional, and" + + " can occur only at the end of the parameter. The '*' character marks a parameter as catch-all," + + " and can occur only at the start of the parameter." + Environment.NewLine + "Parameter name: routeTemplate"); } @@ -349,8 +374,10 @@ namespace Microsoft.AspNet.Routing.Template.Tests { ExceptionAssert.Throws( () => TemplateParser.Parse("{a}/{}/{z}", _inlineConstraintResolver), - "The route parameter name '' is invalid. Route parameter names must be non-empty and cannot contain these characters: '{', '}', '/'. " + - "The '?' character marks a parameter as optional, and can only occur at the end of the parameter." + Environment.NewLine + + "The route parameter name '' is invalid. Route parameter names must be non-empty and cannot" + + " contain these characters: '{', '}', '/'. The '?' character marks a parameter as optional, and" + + " can occur only at the end of the parameter. The '*' character marks a parameter as catch-all," + + " and can occur only at the start of the parameter." + Environment.NewLine + "Parameter name: routeTemplate"); } @@ -359,8 +386,10 @@ namespace Microsoft.AspNet.Routing.Template.Tests { ExceptionAssert.Throws( () => TemplateParser.Parse("{Controller}.mvc/{?}", _inlineConstraintResolver), - "The route parameter name '' is invalid. Route parameter names must be non-empty and cannot contain these characters: '{', '}', '/'. " + - "The '?' character marks a parameter as optional, and can only occur at the end of the parameter." + Environment.NewLine + + "The route parameter name '' is invalid. Route parameter names must be non-empty and cannot" + + " contain these characters: '{', '}', '/'. The '?' character marks a parameter as optional, and" + + " can occur only at the end of the parameter. The '*' character marks a parameter as catch-all," + + " and can occur only at the start of the parameter." + Environment.NewLine + "Parameter name: routeTemplate"); } @@ -423,8 +452,10 @@ namespace Microsoft.AspNet.Routing.Template.Tests { ExceptionAssert.Throws( () => TemplateParser.Parse("{foor?b}", _inlineConstraintResolver), - "The route parameter name 'foor?b' is invalid. Route parameter names must be non-empty and cannot contain these characters: '{', '}', '/'. " + - "The '?' character marks a parameter as optional, and can only occur at the end of the parameter." + Environment.NewLine + + "The route parameter name 'foor?b' is invalid. Route parameter names must be non-empty and cannot" + + " contain these characters: '{', '}', '/'. The '?' character marks a parameter as optional, and" + + " can occur only at the end of the parameter. The '*' character marks a parameter as catch-all," + + " and can occur only at the start of the parameter." + Environment.NewLine + "Parameter name: routeTemplate"); }