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); } }