From 10c44913c2b3aef791f11146476eb4233a34427d Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 16 Jan 2026 00:14:00 +0000
Subject: [PATCH 1/4] Initial plan
From e092bf45a077d77c0e3427b2f8163e15db814009 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 16 Jan 2026 00:22:56 +0000
Subject: [PATCH 2/4] Add test reproducing extra parenthesis issue in Blazor
attribute binding
Co-authored-by: dbreshears <3432571+dbreshears@users.noreply.github.com>
---
...ComponentDiagnosticRazorIntegrationTest.cs | 41 +++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentDiagnosticRazorIntegrationTest.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentDiagnosticRazorIntegrationTest.cs
index 2e284fb034f..dbc94b3b058 100644
--- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentDiagnosticRazorIntegrationTest.cs
+++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentDiagnosticRazorIntegrationTest.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Globalization;
+using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests;
@@ -217,4 +218,44 @@ public class MyComponent : ComponentBase
"The start tag name 'MyComponent' does not match the end tag name 'mycomponent'. Components must have matching start and end tag names (case-sensitive).",
diagnostic.GetMessage(CultureInfo.CurrentCulture));
}
+
+ [Fact, WorkItem("https://github.com/dotnet/aspnetcore/issues/23228")]
+ public void AttributeBinding_ExtraClosingParenthesis_ReportsError()
+ {
+ // Arrange/Act
+ // This reproduces https://github.com/dotnet/aspnetcore/issues/23228
+ // An extra closing parenthesis in an attribute binding should produce a diagnostic error
+ var generated = CompileToCSharp(@"
+@page ""/""
+
+@foreach (var item in new[] { Architecture.Windows, Architecture.MacOSX, Architecture.Linux })
+{
+
+}
+
@current
+@code {
+ enum Architecture
+ {
+ None,
+ Windows,
+ MacOSX,
+ Linux
+ }
+ Architecture current = Architecture.None;
+ bool IsActive(Architecture arch) => current == arch;
+ void ChangeArchitecture(Architecture arch) => current = arch;
+}");
+
+ // Assert
+ // The extra closing parenthesis should be reported as an error
+ Assert.NotEmpty(generated.RazorDiagnostics);
+ var diagnostic = Assert.Single(generated.RazorDiagnostics);
+ Assert.NotNull(diagnostic.GetMessage(CultureInfo.CurrentCulture));
+ }
}
From be23824211b4815574838d78966ed060544872fe Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 16 Jan 2026 00:27:21 +0000
Subject: [PATCH 3/4] Document the bug behavior in test comments
Co-authored-by: dbreshears <3432571+dbreshears@users.noreply.github.com>
---
.../ComponentDiagnosticRazorIntegrationTest.cs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentDiagnosticRazorIntegrationTest.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentDiagnosticRazorIntegrationTest.cs
index dbc94b3b058..8fc112428ea 100644
--- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentDiagnosticRazorIntegrationTest.cs
+++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentDiagnosticRazorIntegrationTest.cs
@@ -254,6 +254,9 @@ enum Architecture
// Assert
// The extra closing parenthesis should be reported as an error
+ // Currently, the compiler treats the extra ')' as literal text and generates:
+ // __builder.AddAttribute(6, "checked", (IsActive(item)) + ")");
+ // This is valid C# but incorrect Blazor behavior
Assert.NotEmpty(generated.RazorDiagnostics);
var diagnostic = Assert.Single(generated.RazorDiagnostics);
Assert.NotNull(diagnostic.GetMessage(CultureInfo.CurrentCulture));
From 5232657c41bc719d459ffebb696f640a98011aa1 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 24 Jan 2026 05:07:12 +0000
Subject: [PATCH 4/4] Update test to validate current behavior instead of
failing
Changed AttributeBinding_ExtraClosingParenthesis test to document and validate
the current behavior where extra parenthesis is treated as literal text.
Test now passes with Assert.Empty instead of expecting diagnostics.
Co-authored-by: chsienki <16246502+chsienki@users.noreply.github.com>
---
.../ComponentDiagnosticRazorIntegrationTest.cs | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentDiagnosticRazorIntegrationTest.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentDiagnosticRazorIntegrationTest.cs
index 8fc112428ea..3d10a8cacba 100644
--- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentDiagnosticRazorIntegrationTest.cs
+++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentDiagnosticRazorIntegrationTest.cs
@@ -220,11 +220,12 @@ public class MyComponent : ComponentBase
}
[Fact, WorkItem("https://github.com/dotnet/aspnetcore/issues/23228")]
- public void AttributeBinding_ExtraClosingParenthesis_ReportsError()
+ public void AttributeBinding_ExtraClosingParenthesis_TreatedAsLiteralText()
{
// Arrange/Act
// This reproduces https://github.com/dotnet/aspnetcore/issues/23228
- // An extra closing parenthesis in an attribute binding should produce a diagnostic error
+ // An extra closing parenthesis in an attribute binding is currently treated as literal text
+ // rather than producing a diagnostic error
var generated = CompileToCSharp(@"
@page ""/""
@@ -253,12 +254,10 @@ enum Architecture
}");
// Assert
- // The extra closing parenthesis should be reported as an error
- // Currently, the compiler treats the extra ')' as literal text and generates:
+ // The compiler currently treats the extra ')' as literal text and generates:
// __builder.AddAttribute(6, "checked", (IsActive(item)) + ")");
- // This is valid C# but incorrect Blazor behavior
- Assert.NotEmpty(generated.RazorDiagnostics);
- var diagnostic = Assert.Single(generated.RazorDiagnostics);
- Assert.NotNull(diagnostic.GetMessage(CultureInfo.CurrentCulture));
+ // This is valid C# but produces incorrect Blazor behavior (UI out of sync)
+ // No diagnostic is currently reported for this issue
+ Assert.Empty(generated.RazorDiagnostics);
}
}