diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/Properties/Resources.Designer.cs
index 8764d1a97a..2c5278ec45 100644
--- a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/Properties/Resources.Designer.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/Properties/Resources.Designer.cs
@@ -262,6 +262,20 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
internal static string FormatPageDirectiveCannotBeImported(object p0, object p1)
=> string.Format(CultureInfo.CurrentCulture, GetString("PageDirectiveCannotBeImported"), p0, p1);
+ ///
+ /// The '@{0}' directive must exist at the top of the file. Only comments and whitespace are allowed before the '@{0}' directive.
+ ///
+ internal static string PageDirectiveMustExistAtTheTopOfFile
+ {
+ get => GetString("PageDirectiveMustExistAtTheTopOfFile");
+ }
+
+ ///
+ /// The '@{0}' directive must exist at the top of the file. Only comments and whitespace are allowed before the '@{0}' directive.
+ ///
+ internal static string FormatPageDirectiveMustExistAtTheTopOfFile(object p0)
+ => string.Format(CultureInfo.CurrentCulture, GetString("PageDirectiveMustExistAtTheTopOfFile"), p0);
+
///
/// Mark the page as a Razor Page.
///
diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/RazorExtensionsDiagnosticFactory.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/RazorExtensionsDiagnosticFactory.cs
index 1e2f6a1f7e..74adb4fe93 100644
--- a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/RazorExtensionsDiagnosticFactory.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/RazorExtensionsDiagnosticFactory.cs
@@ -113,5 +113,19 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
return diagnostic;
}
+
+ internal static readonly RazorDiagnosticDescriptor PageDirective_MustExistAtTheTopOfFile =
+ new RazorDiagnosticDescriptor(
+ $"{DiagnosticPrefix}3906",
+ () => Resources.PageDirectiveMustExistAtTheTopOfFile,
+ RazorDiagnosticSeverity.Error);
+
+ public static RazorDiagnostic CreatePageDirective_MustExistAtTheTopOfFile(SourceSpan source)
+ {
+ var fileName = Path.GetFileName(source.FilePath);
+ var diagnostic = RazorDiagnostic.Create(PageDirective_MustExistAtTheTopOfFile, source, PageDirective.Directive.Directive);
+
+ return diagnostic;
+ }
}
}
diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/RazorPageDocumentClassifierPass.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/RazorPageDocumentClassifierPass.cs
index a4959dded2..63e794fed5 100644
--- a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/RazorPageDocumentClassifierPass.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/RazorPageDocumentClassifierPass.cs
@@ -11,6 +11,25 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
{
public static readonly string RazorPageDocumentKind = "mvc.1.0.razor-page";
+ private static readonly RazorProjectEngine LeadingDirectiveParsingEngine = RazorProjectEngine.Create(
+ RazorConfiguration.Default,
+ RazorProjectFileSystem.Create("/"),
+ builder =>
+ {
+ for (var i = builder.Phases.Count - 1; i >= 0; i--)
+ {
+ var phase = builder.Phases[i];
+ builder.Phases.RemoveAt(i);
+ if (phase is IRazorDocumentClassifierPhase)
+ {
+ break;
+ }
+ }
+
+ RazorExtensions.Register(builder);
+ builder.Features.Add(new LeadingDirectiveParserOptionsFeature());
+ });
+
protected override string DocumentKind => RazorPageDocumentKind;
protected override bool IsMatch(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
@@ -58,6 +77,34 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
pageDirective.DirectiveNode.Diagnostics.Add(
RazorExtensionsDiagnosticFactory.CreatePageDirective_CannotBeImported(pageDirective.DirectiveNode.Source.Value));
}
+ else
+ {
+ // The document contains a page directive and it is not imported.
+ // We now want to make sure this page directive exists at the top of the file.
+ // We are going to do that by re-parsing the document until the very first line that is not Razor comment
+ // or whitespace. We then make sure the page directive still exists in the re-parsed IR tree.
+ var leadingDirectiveCodeDocument = RazorCodeDocument.Create(codeDocument.Source);
+ LeadingDirectiveParsingEngine.Engine.Process(leadingDirectiveCodeDocument);
+
+ var leadingDirectiveDocumentIRNode = leadingDirectiveCodeDocument.GetDocumentIntermediateNode();
+ if (!PageDirective.TryGetPageDirective(leadingDirectiveDocumentIRNode, out var _))
+ {
+ // The page directive is not the leading directive. Add an error.
+ // Note: Adding the error to the top-level document node because the directive node will be removed by a later optimization pass.
+ document.Diagnostics.Add(
+ RazorExtensionsDiagnosticFactory.CreatePageDirective_MustExistAtTheTopOfFile(pageDirective.DirectiveNode.Source.Value));
+ }
+ }
+ }
+
+ private class LeadingDirectiveParserOptionsFeature : RazorEngineFeatureBase, IConfigureRazorParserOptionsFeature
+ {
+ public int Order { get; }
+
+ public void Configure(RazorParserOptionsBuilder options)
+ {
+ options.ParseLeadingDirectives = true;
+ }
}
}
}
diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/Resources.resx b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/Resources.resx
index 2bf9043ca6..c38bccb7fb 100644
--- a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/Resources.resx
+++ b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/Resources.resx
@@ -171,6 +171,9 @@
The '@{0}' directive specified in {1} file will not be imported. The directive must appear at the top of each Razor cshtml file.
+
+ The '@{0}' directive must precede all other elements defined in a Razor file.
+
Mark the page as a Razor Page.
diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/IntegrationTests/CodeGenerationIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/IntegrationTests/CodeGenerationIntegrationTest.cs
index bcddca531e..014aec689e 100644
--- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/IntegrationTests/CodeGenerationIntegrationTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/IntegrationTests/CodeGenerationIntegrationTest.cs
@@ -282,6 +282,14 @@ public class AllTagHelper : {typeof(TagHelper).FullName}
RunRuntimeTest(compilation);
}
+
+ [Fact]
+ public void RazorPageWithNoLeadingPageDirective_Runtime()
+ {
+ var compilation = BaseCompilation;
+
+ RunRuntimeTest(compilation);
+ }
#endregion
#region DesignTime
@@ -561,6 +569,14 @@ public class AllTagHelper : {typeof(TagHelper).FullName}
RunDesignTimeTest(compilation);
}
+
+ [Fact]
+ public void RazorPageWithNoLeadingPageDirective_DesignTime()
+ {
+ var compilation = BaseCompilation;
+
+ RunDesignTimeTest(compilation);
+ }
#endregion
private void RunRuntimeTest(
diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/RazorPageDocumentClassifierPassTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/RazorPageDocumentClassifierPassTest.cs
index 6a21674f2e..9f8623a332 100644
--- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/RazorPageDocumentClassifierPassTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/RazorPageDocumentClassifierPassTest.cs
@@ -1,6 +1,7 @@
// 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 Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Xunit;
@@ -35,6 +36,70 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
Assert.Equal(expectedDiagnostic, diagnostic);
}
+ [Fact]
+ public void RazorPageDocumentClassifierPass_LogsErrorIfDirectiveNotAtTopOfFile()
+ {
+ // Arrange
+ var sourceSpan = new SourceSpan(
+ "Test.cshtml",
+ absoluteIndex: 14 + Environment.NewLine.Length * 2,
+ lineIndex: 2,
+ characterIndex: 0,
+ length: 5 + Environment.NewLine.Length);
+
+ var expectedDiagnostic = RazorExtensionsDiagnosticFactory.CreatePageDirective_MustExistAtTheTopOfFile(sourceSpan);
+ var content = @"
+@somethingelse
+@page
+";
+ var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create(content, "Test.cshtml"));
+
+ var engine = CreateEngine();
+ var irDocument = CreateIRDocument(engine, codeDocument);
+ var pass = new RazorPageDocumentClassifierPass
+ {
+ Engine = engine
+ };
+
+ // Act
+ pass.Execute(codeDocument, irDocument);
+ var visitor = new Visitor();
+ visitor.Visit(irDocument);
+
+ // Assert
+ var documentNode = codeDocument.GetDocumentIntermediateNode();
+ var diagnostic = Assert.Single(documentNode.Diagnostics);
+ Assert.Equal(expectedDiagnostic, diagnostic);
+ }
+
+ [Fact]
+ public void RazorPageDocumentClassifierPass_DoesNotLogErrorIfCommentAndWhitespaceBeforeDirective()
+ {
+ // Arrange
+ var content = @"
+@* some comment *@
+
+@page
+";
+ var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create(content, "Test.cshtml"));
+
+ var engine = CreateEngine();
+ var irDocument = CreateIRDocument(engine, codeDocument);
+ var pass = new RazorPageDocumentClassifierPass
+ {
+ Engine = engine
+ };
+
+ // Act
+ pass.Execute(codeDocument, irDocument);
+ var visitor = new Visitor();
+ visitor.Visit(irDocument);
+
+ // Assert
+ var documentNode = codeDocument.GetDocumentIntermediateNode();
+ Assert.Empty(documentNode.Diagnostics);
+ }
+
[Fact]
public void RazorPageDocumentClassifierPass_SetsDocumentKind()
{
diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml
new file mode 100644
index 0000000000..5172f8f791
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml
@@ -0,0 +1,2 @@
+
Some text here.
+@page
diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.codegen.cs
new file mode 100644
index 0000000000..ec8a4fd5c9
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.codegen.cs
@@ -0,0 +1,42 @@
+//
+#pragma warning disable 1591
+namespace AspNetCore
+{
+ #line hidden
+ using TModel = global::System.Object;
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ using Microsoft.AspNetCore.Mvc;
+ using Microsoft.AspNetCore.Mvc.Rendering;
+ using Microsoft.AspNetCore.Mvc.ViewFeatures;
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective : global::Microsoft.AspNetCore.Mvc.RazorPages.Page
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async override global::System.Threading.Tasks.Task ExecuteAsync()
+ {
+ }
+ #pragma warning restore 1998
+ [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
+ public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
+ [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
+ public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
+ [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
+ public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }
+ [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
+ public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; }
+ [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
+ public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; }
+ public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData;
+ public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective Model => ViewData.Model;
+ }
+}
+#pragma warning restore 1591
diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.diagnostics.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.diagnostics.txt
new file mode 100644
index 0000000000..393b35646e
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.diagnostics.txt
@@ -0,0 +1 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml(2,1): Error RZ3906: The '@page' directive must precede all other elements defined in a Razor file.
diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.ir.txt
new file mode 100644
index 0000000000..c21d9fc82c
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.ir.txt
@@ -0,0 +1,46 @@
+Document -
+ NamespaceDeclaration - - AspNetCore
+ UsingDirective - - TModel = global::System.Object
+ UsingDirective - (1:0,1 [12] ) - System
+ UsingDirective - (16:1,1 [32] ) - System.Collections.Generic
+ UsingDirective - (51:2,1 [17] ) - System.Linq
+ UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks
+ UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc
+ UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering
+ UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective - global::Microsoft.AspNetCore.Mvc.RazorPages.Page -
+ DesignTimeDirective -
+ DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper
+ DirectiveToken - (294:7,71 [4] ) - Html
+ DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
+ DirectiveToken - (363:8,63 [4] ) - Json
+ DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper
+ DirectiveToken - (431:9,62 [9] ) - Component
+ DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper
+ DirectiveToken - (494:10,52 [3] ) - Url
+ DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider
+ DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider
+ DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor
+ DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor
+ DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [28] RazorPageWithNoLeadingPageDirective.cshtml)
+ IntermediateToken - (0:0,0 [5] RazorPageWithNoLeadingPageDirective.cshtml) - Html -
+ IntermediateToken - (5:0,5 [15] RazorPageWithNoLeadingPageDirective.cshtml) - Html - Some text here.
+ IntermediateToken - (20:0,20 [6] RazorPageWithNoLeadingPageDirective.cshtml) - Html -
+ IntermediateToken - (26:0,26 [2] RazorPageWithNoLeadingPageDirective.cshtml) - Html - \n
+ Inject -
+ Inject -
+ Inject -
+ Inject -
+ Inject -
+ CSharpCode -
+ IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData;
+ CSharpCode -
+ IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective Model => ViewData.Model;
diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.mappings.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_DesignTime.mappings.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.codegen.cs
new file mode 100644
index 0000000000..0b0bd358fa
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.codegen.cs
@@ -0,0 +1,41 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "1d35b023a80ffd4cbf92549aae24d6c47f4af7e5"
+//
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective), @"mvc.1.0.razor-page", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml")]
+[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective), null)]
+namespace AspNetCore
+{
+ #line hidden
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ using Microsoft.AspNetCore.Mvc;
+ using Microsoft.AspNetCore.Mvc.Rendering;
+ using Microsoft.AspNetCore.Mvc.ViewFeatures;
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"1d35b023a80ffd4cbf92549aae24d6c47f4af7e5", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective : global::Microsoft.AspNetCore.Mvc.RazorPages.Page
+ {
+ #pragma warning disable 1998
+ public async override global::System.Threading.Tasks.Task ExecuteAsync()
+ {
+ BeginContext(0, 28, true);
+ WriteLiteral("Some text here.
\r\n");
+ EndContext();
+ }
+ #pragma warning restore 1998
+ [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
+ public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
+ [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
+ public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
+ [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
+ public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }
+ [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
+ public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; }
+ [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
+ public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; }
+ public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData;
+ public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective Model => ViewData.Model;
+ }
+}
+#pragma warning restore 1591
diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.diagnostics.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.diagnostics.txt
new file mode 100644
index 0000000000..393b35646e
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.diagnostics.txt
@@ -0,0 +1 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml(2,1): Error RZ3906: The '@page' directive must precede all other elements defined in a Razor file.
diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.ir.txt
new file mode 100644
index 0000000000..764b704909
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective_Runtime.ir.txt
@@ -0,0 +1,33 @@
+Document -
+ RazorCompiledItemAttribute -
+ CSharpCode -
+ IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPageWithNoLeadingPageDirective.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective), null)]
+ NamespaceDeclaration - - AspNetCore
+ UsingDirective - (1:0,1 [14] ) - System
+ UsingDirective - (16:1,1 [34] ) - System.Collections.Generic
+ UsingDirective - (51:2,1 [19] ) - System.Linq
+ UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks
+ UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc
+ UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering
+ UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective - global::Microsoft.AspNetCore.Mvc.RazorPages.Page -
+ MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode -
+ IntermediateToken - - CSharp - BeginContext(0, 28, true);
+ HtmlContent - (0:0,0 [28] RazorPageWithNoLeadingPageDirective.cshtml)
+ IntermediateToken - (0:0,0 [5] RazorPageWithNoLeadingPageDirective.cshtml) - Html -
+ IntermediateToken - (5:0,5 [15] RazorPageWithNoLeadingPageDirective.cshtml) - Html - Some text here.
+ IntermediateToken - (20:0,20 [6] RazorPageWithNoLeadingPageDirective.cshtml) - Html -
+ IntermediateToken - (26:0,26 [2] RazorPageWithNoLeadingPageDirective.cshtml) - Html - \n
+ CSharpCode -
+ IntermediateToken - - CSharp - EndContext();
+ Inject -
+ Inject -
+ Inject -
+ Inject -
+ Inject -
+ CSharpCode -
+ IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData;
+ CSharpCode -
+ IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPageWithNoLeadingPageDirective Model => ViewData.Model;