Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2373,6 +2373,20 @@ @layout System.Object
CompileToAssembly(generated);
}

[IntegrationTestFact, WorkItem("https://github.com/dotnet/razor/issues/8340")]
public void LayoutDirective_Null()
{
// Act
var generated = CompileToCSharp("""
@layout null
""");

// Assert
AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
CompileToAssembly(generated);
}

[IntegrationTestFact]
public void Component_AddContent_Multiline()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ public void SupportsLayoutDeclarations()
Assert.NotNull(layoutAttribute);
}

[Fact]
public void SupportsLayoutNullDeclaration()
{
// Arrange/Act
var component = CompileToComponent(
"@layout null\n" +
"Hello");

// Assert - when layout is set to null, no layout attribute should be generated
Assert.Null(component.GetAttributes().FirstOrDefault(a => a.AttributeClass.Name == "LayoutAttribute"));
}

[Fact]
public void SupportsImplementsDeclarations()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// <auto-generated/>
#pragma warning disable 1591
namespace Test
{
#line default
using global::System;
using global::System.Collections.Generic;
using global::System.Linq;
using global::System.Threading.Tasks;
using global::Microsoft.AspNetCore.Components;
#line default
#line hidden
#nullable restore
public partial class TestComponent : global::Microsoft.AspNetCore.Components.ComponentBase
#nullable disable
{
#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
((global::System.Action)(() => {
}
))();
}
#pragma warning restore 219
#pragma warning disable 0414
private static object __o = null;
#pragma warning restore 0414
#pragma warning disable 1998
protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
{
}
#pragma warning restore 1998
}
}
#pragma warning restore 1591
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Document -
NamespaceDeclaration - - Test
UsingDirective - (3:1,1 [20] ) - global::System
UsingDirective - (26:2,1 [40] ) - global::System.Collections.Generic
UsingDirective - (69:3,1 [25] ) - global::System.Linq
UsingDirective - (97:4,1 [36] ) - global::System.Threading.Tasks
UsingDirective - (136:5,1 [45] ) - global::Microsoft.AspNetCore.Components
ClassDeclaration - - public partial - TestComponent - global::Microsoft.AspNetCore.Components.ComponentBase -
DesignTimeDirective -
DirectiveToken - (8:0,8 [4] x:\dir\subdir\Test\TestComponent.cshtml) - null
CSharpCode -
IntermediateToken - - CSharp - #pragma warning disable 0414
CSharpCode -
IntermediateToken - - CSharp - private static object __o = null;
CSharpCode -
IntermediateToken - - CSharp - #pragma warning restore 0414
MethodDeclaration - - protected override - void - BuildRenderTree
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// <auto-generated/>
#pragma warning disable 1591
namespace Test
{
#line default
using global::System;
using global::System.Collections.Generic;
using global::System.Linq;
using global::System.Threading.Tasks;
using global::Microsoft.AspNetCore.Components;
#line default
#line hidden
#nullable restore
public partial class TestComponent : global::Microsoft.AspNetCore.Components.ComponentBase
#nullable disable
{
#pragma warning disable 1998
protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
{
}
#pragma warning restore 1998
}
}
#pragma warning restore 1591
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Document -
NamespaceDeclaration - - Test
UsingDirective - (3:1,1 [20] ) - global::System
UsingDirective - (26:2,1 [40] ) - global::System.Collections.Generic
UsingDirective - (69:3,1 [25] ) - global::System.Linq
UsingDirective - (97:4,1 [36] ) - global::System.Threading.Tasks
UsingDirective - (136:5,1 [45] ) - global::Microsoft.AspNetCore.Components
ClassDeclaration - - public partial - TestComponent - global::Microsoft.AspNetCore.Components.ComponentBase -
MethodDeclaration - - protected override - void - BuildRenderTree
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Linq;
using System.Threading;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
Expand Down Expand Up @@ -33,6 +34,12 @@ protected override void ExecuteCore(
return;
}

// If the layout is explicitly set to null, don't generate a layout attribute
if (string.Equals(token.Content, "null", StringComparison.Ordinal))
{
return;
}

var attributeNode = new CSharpCodeIntermediateNode();
attributeNode.Children.AddRange([
IntermediateNodeFactory.CSharpToken($"[global::{ComponentsApi.LayoutAttribute.FullTypeName}(typeof("),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ private void WriteDesignTimeDirectiveToken(CodeRenderingContext context, DesignT
break;
}

// Skip validation for "null" which is used to disable layouts
if (string.Equals(node.Content, "null", StringComparison.Ordinal))
{
break;
}

// {node.Content} __typeHelper = default({node.Content});
using (context.BuildLinePragma(node.Source))
{
Expand Down
Loading