Skip to content

CS8669 when using runtime compilation and the project has nullable enabled #53967

Open
@sandermvanvliet-stack

Description

@sandermvanvliet-stack

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.

(click for full stack trace)

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions