CS8669 when using runtime compilation and the project has nullable enabled
I have an interesting case where I have Razor runtime compilation enabled and the view is in a project that has <Nullable>enable</Nullable> in the project file.
What I'm seeing
Given a view like this:
@using MyModel
@functions
{
public void StatusIndicator(bool success, string? reason)
{
// Omitted for brevity
}
}
<div>
<p>@{ StatusIndicator(Model.Success, Model.Reason); }</p>
</div>
where MyModel is:
public class MyModel
{
public bool Success { get; set; }
public string? Reason { get; set; }
}
Project file is like this:
<Project>
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
</PropertyGroup>
</Project>
When enabling Razor runtime compilation and navigating to the route that uses this view I get the error:
The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.
When disabling Razor runtime compilation and navigating to the route that uses this view it will be rendered normally.
Suspicions
For (I think..) both runtime and build compilation, the view is passed through the Razor source generator exactly in the same way so should amount to the same code. By catching the exception (see above) I've managed to pull out the runtime generated code and using the EmitCompilerGeneratedFiles MSBuild property in the project I've also managed to capture the build time generated code.
Comparing the two I can see some slight differences (namespace name and file paths) but otherwise they're similar.
My suspicion is that:
- For build time Razor compilation the code is first generated (using the Razor source generator) and then compiled inside the actual project.
- For runtime Razor compilation, the code is generated but compiled in-memory in an isolated project
As it's not part of the actual project, the setting for Nullable isn't taken from that project which leads to this result that the compilation thinks that Nullable is not enabled (where it is enabled in the actual project).
Versions
Visual Studio Version 17.8.3
dotnet --info:
.NET SDK (reflecting any global.json):
Version: 6.0.413
Commit: 10710f7d8e
Runtime Environment:
OS Name: Windows
OS Version: 10.0.22631
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\6.0.413\
Host:
Version: 8.0.0
Architecture: x64
Commit: 5535e31a71
.NET SDKs installed:
6.0.300 [C:\Program Files\dotnet\sdk]
6.0.405 [C:\Program Files\dotnet\sdk]
6.0.408 [C:\Program Files\dotnet\sdk]
6.0.413 [C:\Program Files\dotnet\sdk]
7.0.115 [C:\Program Files\dotnet\sdk]
8.0.100 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 5.0.14 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.16 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.25 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.14 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.16 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.25 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.13 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.16 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.25 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 7.0.14 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 7.0.15 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation Version 6.0.5
@sandermvanvliet-stack thanks for the detailed analysis! That certainly seems like a plausible explanation for what is happening.
@jaredpar @danroth27 Runtime compilation lives in aspnetcore, but I guess we're the closest to its owners. Do we want to track issues for it here, or over there?
@jaredpar @danroth27 Runtime compilation lives in aspnetcore, but I guess we're the closest to its owners. Do we want to track issues for it here, or over there?
Let's track the issue in the repo where the corresponding code lives. If this is an issue with runtime compilation and not the compiler, then it should move to the aspnetcore repo.
If there is any additional info needed give me a shout 👍