diff --git a/src/Microsoft.AspNet.Razor/Parser/CSharpCodeParser.cs b/src/Microsoft.AspNet.Razor/Parser/CSharpCodeParser.cs
index d06bf98b0..8aaa6ae0f 100644
--- a/src/Microsoft.AspNet.Razor/Parser/CSharpCodeParser.cs
+++ b/src/Microsoft.AspNet.Razor/Parser/CSharpCodeParser.cs
@@ -224,6 +224,14 @@ private void AfterTransition()
}
else
{
+ if (CurrentSymbol.Content.Equals(SyntaxConstants.CSharp.HelperKeyword))
+ {
+ Context.OnError(
+ CurrentLocation,
+ RazorResources.FormatParseError_HelperDirectiveNotAvailable(SyntaxConstants.CSharp.HelperKeyword),
+ CurrentSymbol.Content.Length);
+ }
+
Context.CurrentBlock.Type = BlockType.Expression;
Context.CurrentBlock.ChunkGenerator = new ExpressionChunkGenerator();
ImplicitExpression();
diff --git a/src/Microsoft.AspNet.Razor/Parser/SyntaxConstants.cs b/src/Microsoft.AspNet.Razor/Parser/SyntaxConstants.cs
index 2a6b2a53d..47a0f9cd5 100644
--- a/src/Microsoft.AspNet.Razor/Parser/SyntaxConstants.cs
+++ b/src/Microsoft.AspNet.Razor/Parser/SyntaxConstants.cs
@@ -27,6 +27,9 @@ public static class CSharp
public static readonly string ElseIfKeyword = "else if";
public static readonly string NamespaceKeyword = "namespace";
public static readonly string ClassKeyword = "class";
+
+ // Not supported. Only used for error cases.
+ public static readonly string HelperKeyword = "helper";
}
}
}
diff --git a/src/Microsoft.AspNet.Razor/Properties/RazorResources.Designer.cs b/src/Microsoft.AspNet.Razor/Properties/RazorResources.Designer.cs
index 4ffee4c45..38433e297 100644
--- a/src/Microsoft.AspNet.Razor/Properties/RazorResources.Designer.cs
+++ b/src/Microsoft.AspNet.Razor/Properties/RazorResources.Designer.cs
@@ -1546,6 +1546,22 @@ internal static string FormatTagHelperParseTreeRewriter_InvalidNestedTag(object
return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperParseTreeRewriter_InvalidNestedTag"), p0, p1, p2);
}
+ ///
+ /// The {0} directive is not supported.
+ ///
+ internal static string ParseError_HelperDirectiveNotAvailable
+ {
+ get { return GetString("ParseError_HelperDirectiveNotAvailable"); }
+ }
+
+ ///
+ /// The {0} directive is not supported.
+ ///
+ internal static string FormatParseError_HelperDirectiveNotAvailable(object p0)
+ {
+ return string.Format(CultureInfo.CurrentCulture, GetString("ParseError_HelperDirectiveNotAvailable"), p0);
+ }
+
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);
diff --git a/src/Microsoft.AspNet.Razor/RazorResources.resx b/src/Microsoft.AspNet.Razor/RazorResources.resx
index 0fe6f2b01..45c0228a8 100644
--- a/src/Microsoft.AspNet.Razor/RazorResources.resx
+++ b/src/Microsoft.AspNet.Razor/RazorResources.resx
@@ -425,4 +425,7 @@ Instead, wrap the contents of the block in "{{}}":
The <{0}> tag is not allowed by parent <{1}> tag helper. Only child tag helper(s) targeting tag name(s) '{2}' are allowed.
+
+ The {0} directive is not supported.
+
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Razor.Test/Parser/CSharp/CSharpErrorTest.cs b/test/Microsoft.AspNet.Razor.Test/Parser/CSharp/CSharpErrorTest.cs
index 409da532c..7d023220c 100644
--- a/test/Microsoft.AspNet.Razor.Test/Parser/CSharp/CSharpErrorTest.cs
+++ b/test/Microsoft.AspNet.Razor.Test/Parser/CSharp/CSharpErrorTest.cs
@@ -27,6 +27,21 @@ public void ParseBlockHandlesQuotesAfterTransition()
length: 1));
}
+ [Fact]
+ public void ParseBlockWithHelperDirectiveProducesError()
+ {
+ ParseBlockTest("@helper fooHelper { }",
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("helper")
+ .AsImplicitExpression(KeywordSet)
+ .Accepts(AcceptedCharacters.NonWhiteSpace)),
+ new RazorError(
+ RazorResources.FormatParseError_HelperDirectiveNotAvailable(SyntaxConstants.CSharp.HelperKeyword),
+ new SourceLocation(1, 0, 1),
+ length: 6));
+ }
+
[Fact]
public void ParseBlockCapturesWhitespaceToEndOfLineInInvalidUsingStatementAndTreatsAsFileCode()
{