Description
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