-
Notifications
You must be signed in to change notification settings - Fork 10.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use given model nullability in razor pages #37510
Comments
In this particular case, it's valid for the model to be null i.e. you could do
and the framework allows this. Introducing a null check in this code path would be a breaking change. A possible workaround might be to introduce a base type for your view - https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-5.0#inherits that has the model property annotated for nullability differently and use that in your app. I'm leaving the issue open in case we'd like to try and address this in a later release. |
FYI @DamianEdwards |
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process. |
Ye, we are aware that it's just an annotation disconnected from the back end. Was just thinking that matching razor model with your backend would result in better experience compared to just disabling nullability all together to avoid compile errors. Good idea about the base view will try to do that 👍 |
Tried using custom razor page model, but as expected razor doesn't handle it well today. For example using
Doesn't compile at all, because nullability context is disabled? Even though the project has it enabled.
|
I'm having this issue too. I believe it was wrong to annotate We need a way to fix (opt out of nullable razor models) with one liner at startup. |
This is a show-stopping breaking change if an app has If an application has hundreds (or thousands) of Views, it's going to take awhile adding this 'unofficial' solution to get the app to compile again.
Where was the planning for this feature? What was the official planned recommendation to resolve this issue for the many apps built before .NET 6.0? Hundreds or thousands of errors after upgrading to .NET 6.0 and the best we have at the moment is "a possible workaround"? 🤦♂️🤦♂️🤦♂️🤦♂️ |
Thanks for the feedback. Addressing this is two parts -
My hope is to try and get these tackled as part of an upcoming VS release / .NET servicing release. |
Currently the Razor compiler suppresses nullable annotations within most generated code. https://github.com/dotnet/aspnetcore/issues/39360 tracks addressing this, but that would need a fair bit of work to get right. In the meantime, dotnet/aspnetcore#37510 is affecting a lot of users attempting to turn on nullability in their apps. The value of the `@model` directive appears as part of the class declaration for a Razor View: ```C# @model MyModel? // Results in #nullable disable internal sealed class _Views_Home_Index : RazorPage<MyModel?> // This will produce a warning since it's not within a nullable context ``` The `#nullable disable` precludes the ability of the user to be able to specify a nullable `model`. This change updates the compiler and generates the class declaration within a nullable context, as long as the C# version is recent enough to support nullability. The generated code now looks like: ```C# @model MyModel? // Results in ... #nullable restore // Use the nullability based on the project's global settings internal sealed class _Views_Home_Index : RazorPage<MyModel?> #nullable disable ``` In addition to the class declaration, we also need to generate the properties for `@inject` within a nullable context. This is because all views have an implicit `@inject IHtmlHelper<TModel>` where `TModel` is the model type.
) Currently the Razor compiler suppresses nullable annotations within most generated code. https://github.com/dotnet/aspnetcore/issues/39360 tracks addressing this, but that would need a fair bit of work to get right. In the meantime, dotnet/aspnetcore#37510 is affecting a lot of users attempting to turn on nullability in their apps. The value of the `@model` directive appears as part of the class declaration for a Razor View: ```C# @model MyModel? // Results in #nullable disable internal sealed class _Views_Home_Index : RazorPage<MyModel?> // This will produce a warning since it's not within a nullable context ``` The `#nullable disable` precludes the ability of the user to be able to specify a nullable `model`. This change updates the compiler and generates the class declaration within a nullable context, as long as the C# version is recent enough to support nullability. The generated code now looks like: ```C# @model MyModel? // Results in ... #nullable restore // Use the nullability based on the project's global settings internal sealed class _Views_Home_Index : RazorPage<MyModel?> #nullable disable ``` In addition to the class declaration, we also need to generate the properties for `@inject` within a nullable context. This is because all views have an implicit `@inject IHtmlHelper<TModel>` where `TModel` is the model type.
This is fixed for the 6.0.2 release of the runtime and a compiler change that allows models to be declared as nullable would be available in 17.1 / 6.0.200 version of the .NET SDK. Thanks for all of your feedback! |
@pranavkm Since runtime 6.0.2 seems to be included in the 17.0.6/6.0.102 SDK would those be appropriate, or is there additional work coming in 17.1.x/6.0.2xx? |
I'm a little confused, I just updated my app to 6.0.2 but I'm still getting the analyser message:
This is how I'm using it in index.cshtml @model Foo.Dashboard.DashboardViewModel
<span class="counter-number-related text-capitalize">@("people".ToQuantity(Model.UserOnlineCount, ShowQuantityAs.None))</span> Other people having the same issue: |
So I just tried this with the 6.0.102 SDK installed and the runtime changes work - doing Could you confirm that's the SDK your app is using to build? SDKs typically roll forward, so if you happen to have a 6.0.200 preview SDK installed side-by-side, it'll end up using that instead and not use these changes. You can confirm the SDK that is being used by running Global.json contents: {
"sdk": {
"version": "6.0.102"
}
} |
@pranavkm Thanks for getting back to me, have you set the analysis mode to |
@dotnetshadow setting the AnalysisMode does not change the result for me. Do you see the same error if you build the app from the CLI? If you do, could I bother you to share msbuild binary logs by running Note that binlogs will capture ambient environment variables. |
Funny you should ask, I just tried that and I am getting the warning b\Features\Admin\Dashboard\Index.cshtml(70,97): warning CS8602: Dereference of a possibly null reference. [D:\Programming\Code\Company\StockWatch\src\Foo.Web\Foo.Web.csproj] msbuild binary log |
@dotnetshadow looks like the file was removed. |
Sorry about that I uploaded to a new host |
I was getting the same warning for razor files in Visual Studio and CLI build. Before reinstalling, when I used the "Go to definition" command over public TModel? Model { get; } , but not after. I'm hoping that helps with the diagnostic. |
Thanks @Diego-T. Looking at the build logs, it looks like it's compiling against the right assembly. Could you try installing the SDK from https://dotnet.microsoft.com/en-us/download/dotnet/6.0? It would help narrow down if this is a setup / installer issue. |
@pranavkm That's what I did, I installed the SDK from that link and the warning was cleared. I'm on Windows 11 (22000.493) and used the x64 installer. |
.NET SDK (reflecting any global.json):
Version: 6.0.102
Commit: 02d5242ed7
Runtime Environment:
OS Name: Windows
OS Version: 10.0.19044
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\6.0.102\
Host (useful for support):
Version: 6.0.2
Commit: 839cdfb0ec
.NET SDKs installed:
3.1.201 [C:\Program Files\dotnet\sdk]
3.1.202 [C:\Program Files\dotnet\sdk]
3.1.301 [C:\Program Files\dotnet\sdk]
3.1.416 [C:\Program Files\dotnet\sdk]
5.0.101 [C:\Program Files\dotnet\sdk]
5.0.102 [C:\Program Files\dotnet\sdk]
5.0.103 [C:\Program Files\dotnet\sdk]
5.0.203 [C:\Program Files\dotnet\sdk]
5.0.211 [C:\Program Files\dotnet\sdk]
5.0.400 [C:\Program Files\dotnet\sdk]
5.0.401 [C:\Program Files\dotnet\sdk]
5.0.403 [C:\Program Files\dotnet\sdk]
5.0.405 [C:\Program Files\dotnet\sdk]
6.0.100 [C:\Program Files\dotnet\sdk]
6.0.101 [C:\Program Files\dotnet\sdk]
6.0.102 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 3.1.20 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.22 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.14 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.21 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.22 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.12 [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 6.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.21 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.22 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.12 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.14 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
To install additional .NET runtimes or SDKs:
https://aka.ms/dotnet-download
I will try to reinstall again |
Hi @Diego-T Did you try compiling with the following? I initially didn't have the error but that's because My 'Go to Definition' looks like this |
@dotnetshadow I just tried with that flag |
Thanks @Diego-T @pranavkm. I just reinstalled dotnet-sdk-6.0.102-win-x64.exe seems to work now. Could of been a point in time thing. I rebooted and looks to be working now thanks for all your help guys. This issue can be closed |
@pranavkm Just a note, I did notice the following peculiar issue. Say you have as your model // Index.cshtml
@model Person Then later in the page you might have the following // Index.cshtml
<p>@Model?.Age</p> // notice the ? here (even if it's by accident)
<p>@Model.Age</p> // causes Warning (active) CS8602 Dereference of a possibly null reference. |
@dotnetshadow that's a behavior for the C# compiler and works the same in regular C# code. You could follow up at https://github.com/dotnet/roslyn if you'd like further clarification. |
We are migrating our 5.0 project to 6.0-rc2 and noticed that RazorPage.Model was changed to always be nullable, even though model type in razor file is specified as not null. Because of this, we are getting thousands of compile time errors on any model access outside of
asp-for
expressions likeasp-route-id="@Model.Id"
.Describe the solution you'd like
Would it be possible to change it to
TModel
fromTModel?
?So we can tell the razor page if model is possibly null or not in the view?
Additional context
My guess is that razor doesn't parse nullable models in views, so it wasn't made that way because of that?
The text was updated successfully, but these errors were encountered: