Description
When a .cshtml file contains supplementary Unicode characters (codepoints above U+FFFF, encoded as 4-byte UTF-8 sequences) in its HTML literal content — such as emoji or variation selectors — the .NET 10 Razor compiler incorrectly emits the @functions block content inside the ExecuteAsync method body instead of as class-level members.
This is a regression from .NET 8/9 where the same file compiles correctly with @functions content placed as class members.
Steps to Reproduce
- Create a .cshtml file with emoji characters in HTML literals and a
@functions block:
<p>
<span>😁</span>
<span>💩</span>
<span>🐻</span>
<span>🐳</span>
<span>❤️</span>
<span>🌶️</span>
<span>😶🌫️</span>
<span>👾</span>
<span>🫨</span>
</p>
@functions {
static string Title = "Unicode";
public string SomeProperty => Title;
}
- Build targeting
net10.0
Expected Behavior
The @functions block should be emitted as class-level members, just as it is in .NET 8 and .NET 9.
.NET 8/9 generated code (correct — @functions content after ExecuteAsync closes):
}
#pragma warning restore 1998
#nullable restore
#line (60,13)-(71,1) "Unicode.cshtml"
static string Title = "Unicode";
public string SomeProperty => Title;
#line default
#line hidden
#nullable disable
Actual Behavior
The @functions block content is emitted inside the ExecuteAsync method body, causing compilation errors (static not valid, properties not valid inside method, etc.):
.NET 10 generated code (broken — @functions content before ExecuteAsync closes):
WriteLiteral("</span>\r\n</p>\r\n\r\n");
#nullable restore
#line (60,13)-(71,1) "Unicode.cshtml"
static string Title = "Unicode";
public string SomeProperty => Title;
#line default
#line hidden
#nullable disable
}
#pragma warning restore 1998
This produces errors like:
CS0106: The modifier 'static' is not valid for this item
CS0841: Cannot use local variable before it is declared
CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement
Key Observations
- Only affects files with supplementary Unicode characters (codepoints > U+FFFF, i.e., 4-byte UTF-8 sequences like emoji
F0 9F xx xx or variation selectors F3 A0 xx xx)
- Other
.cshtml files in the same project with @functions blocks but without supplementary Unicode characters compile correctly in .NET 10
- The same file compiles correctly in .NET 8 and .NET 9
- The Razor compiler appears to recognize
@functions (the line mapping (60,13)-(71,1) is identical across versions) but places the content in the wrong location
Workaround
Move code from @functions into a separate .cs helper class and reference it from the .cshtml file. Replace supplementary Unicode character literals in HTML with HTML character references (e.g., 󠄀 instead of the raw U+E0100 character).
Environment
- .NET SDK:
10.0.200-preview.0.26103.119
- Runtime:
10.0.3
- OS: Windows 11 (
10.0.26200)
- Works correctly on: .NET SDK
8.0.418 and 9.0.x
Related
Discovered and worked around in DamianEdwards/RazorSlices@28fecc0
Description
When a .cshtml file contains supplementary Unicode characters (codepoints above U+FFFF, encoded as 4-byte UTF-8 sequences) in its HTML literal content — such as emoji or variation selectors — the .NET 10 Razor compiler incorrectly emits the
@functionsblock content inside theExecuteAsyncmethod body instead of as class-level members.This is a regression from .NET 8/9 where the same file compiles correctly with
@functionscontent placed as class members.Steps to Reproduce
@functionsblock:net10.0Expected Behavior
The
@functionsblock should be emitted as class-level members, just as it is in .NET 8 and .NET 9..NET 8/9 generated code (correct —
@functionscontent afterExecuteAsynccloses):Actual Behavior
The
@functionsblock content is emitted inside theExecuteAsyncmethod body, causing compilation errors (staticnot valid, properties not valid inside method, etc.):.NET 10 generated code (broken —
@functionscontent beforeExecuteAsynccloses):This produces errors like:
CS0106: The modifier 'static' is not valid for this itemCS0841: Cannot use local variable before it is declaredCS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statementKey Observations
F0 9F xx xxor variation selectorsF3 A0 xx xx).cshtmlfiles in the same project with@functionsblocks but without supplementary Unicode characters compile correctly in .NET 10@functions(the line mapping(60,13)-(71,1)is identical across versions) but places the content in the wrong locationWorkaround
Move code from
@functionsinto a separate.cshelper class and reference it from the.cshtmlfile. Replace supplementary Unicode character literals in HTML with HTML character references (e.g.,󠄀instead of the raw U+E0100 character).Environment
10.0.200-preview.0.26103.11910.0.310.0.26200)8.0.418and9.0.xRelated
Discovered and worked around in DamianEdwards/RazorSlices@28fecc0