diff --git a/src/Microsoft.AspNetCore.Routing/Resources.resx b/src/Microsoft.AspNetCore.Routing/Resources.resx
index 52b22d6962..96ecf1f445 100644
--- a/src/Microsoft.AspNetCore.Routing/Resources.resx
+++ b/src/Microsoft.AspNetCore.Routing/Resources.resx
@@ -187,7 +187,7 @@
In a route parameter, '{' and '}' must be escaped with '{{' and '}}'.
- In the segment '{0}', the optional parameter '{1}' is preceded by an invalid segment '{2}'. Only a period (.) can precede an optional parameter.
+ In the segment '{0}', the optional parameter '{1}' is preceded by an invalid segment '{2}'. Only a period (.) can precede an optional parameter.
An optional parameter must be at the end of the segment. In the segment '{0}', optional parameter '{1}' is followed by '{2}'.
diff --git a/src/Microsoft.AspNetCore.Routing/Template/TemplateParser.cs b/src/Microsoft.AspNetCore.Routing/Template/TemplateParser.cs
index ab38bf55f2..4ef9e394de 100644
--- a/src/Microsoft.AspNetCore.Routing/Template/TemplateParser.cs
+++ b/src/Microsoft.AspNetCore.Routing/Template/TemplateParser.cs
@@ -342,20 +342,26 @@ namespace Microsoft.AspNetCore.Routing.Template
// This optional parameter is the last part in the segment
if (i == segment.Parts.Count - 1)
{
- Debug.Assert(segment.Parts[i - 1].IsLiteral);
-
- // the optional parameter is preceded by a period
- if (segment.Parts[i - 1].Text == PeriodString)
+ if(!segment.Parts[i - 1].IsLiteral)
{
- segment.Parts[i - 1].IsOptionalSeperator = true;
- }
- else
- {
- // The optional parameter is preceded by a literal other than period
+ // The optional parameter is preceded by something that is not a literal.
// Example of error message:
- // "In the complex segment {RouteValue}-{param?}, the optional parameter 'param'is preceded
- // by an invalid segment "-". Only valid literal to precede an optional parameter is a
- // period (.).
+ // "In the segment '{RouteValue}-{param?}', the optional parameter 'param' is preceded
+ // by an invalid segment '-'. Only a period (.) can precede an optional parameter.
+ context.Error = string.Format(
+ Resources.TemplateRoute_OptionalParameterCanbBePrecededByPeriod,
+ segment.DebuggerToString(),
+ part.Name,
+ segment.Parts[i - 1].DebuggerToString());
+
+ return false;
+ }
+ if(segment.Parts[i - 1].Text != PeriodString)
+ {
+ // The optional parameter is preceded by a literal other than period.
+ // Example of error message:
+ // "In the segment '{RouteValue}-{param?}', the optional parameter 'param' is preceded
+ // by an invalid segment '-'. Only a period (.) can precede an optional parameter.
context.Error = string.Format(
Resources.TemplateRoute_OptionalParameterCanbBePrecededByPeriod,
segment.DebuggerToString(),
@@ -364,6 +370,7 @@ namespace Microsoft.AspNetCore.Routing.Template
return false;
}
+ segment.Parts[i - 1].IsOptionalSeperator = true;
}
else
{
diff --git a/test/Microsoft.AspNetCore.Routing.Tests/Template/TemplateParserTests.cs b/test/Microsoft.AspNetCore.Routing.Tests/Template/TemplateParserTests.cs
index 140a8292e1..7ffd8f1026 100644
--- a/test/Microsoft.AspNetCore.Routing.Tests/Template/TemplateParserTests.cs
+++ b/test/Microsoft.AspNetCore.Routing.Tests/Template/TemplateParserTests.cs
@@ -545,19 +545,19 @@ namespace Microsoft.AspNetCore.Routing.Template.Tests
+ Environment.NewLine + "Parameter name: routeTemplate");
}
- [Theory(Skip = "Skipped because it causes the test framework to crash")]
+ [Theory]
[InlineData("{p1}-{p2?}", "-")]
[InlineData("{p1}..{p2?}", "..")]
[InlineData("..{p2?}", "..")]
[InlineData("{p1}.abc.{p2?}", ".abc.")]
- [InlineData("{p1}{p2?}", "p1")]
+ [InlineData("{p1}{p2?}", "{p1}")]
public void Parse_ComplexSegment_OptionalParametersSeperatedByPeriod_Invalid(string template, string parameter)
{
// Act and Assert
ExceptionAssert.Throws(
() => TemplateParser.Parse(template),
- "In the complex segment '"+ template +"', the optional parameter 'p2' is preceded by an invalid " +
- "segment '" + parameter +"'. Only valid literal to precede an optional parameter is a period (.)." +
+ "In the segment '"+ template +"', the optional parameter 'p2' is preceded by an invalid " +
+ "segment '" + parameter +"'. Only a period (.) can precede an optional parameter." +
Environment.NewLine + "Parameter name: routeTemplate");
}