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;