dotnet / razor

Compiler and tooling experience for Razor ASP.NET Core apps in Visual Studio, Visual Studio for Mac, and VS Code.
https://asp.net
MIT License
501 stars 191 forks source link

Razor Pages squigglies for internal PageModel implementations #9352

Open lonix1 opened 1 year ago

lonix1 commented 1 year ago

Environment data

dotnet --info output: 7.0.401 VS Code version: 1.82.2 C# Extension version: 2.3.27

OmniSharp log

n/a

Steps to reproduce

Foo.cshtml.cs

internal sealed class FooModel : PageModel {                      // <--------- internal
  public string Name { get; set; } = "Mike";
  // ...
}

Foo.cshtml

@page /foo
@model FooModel
<div>
  Hello @Model.Name      @* red squigglies start at first invocation of Model, till end of document *@
  ...                    @* red squigglies *@
  ...                    @* red squigglies *@
</div>                   @* red squigglies *@

Expected behavior

No errors, no warnings, no squigglies.

Actual behavior

Many red squigglies in vscode. Example:

Inconsistent accessibility: property type 'IHtmlHelper<FooModel>' is less accessible than property 'Pages_Foo.Html' CS0053
Inconsistent accessibility: property type 'IHtmlHelper<FooModel>' is less accessible than property 'Pages_Foo.ViewData' CS0053
Inconsistent accessibility: property type 'IHtmlHelper<FooModel>' is less accessible than property 'Pages_Foo.Model' CS0053

Additional context

Even though reported as errors, the app works. It's perfectly valid code.

When I change internal to public, the squigglies disappear. But I don't want to do that, as the code I've written is best practice.

The above example is simplistic. For a real RP page, of non-trivial length, the entire editor is filled with red squigglies. It's completely unusable.

davidwengier commented 1 year ago

Thanks for reporting this issue. I'm going to move it to the Razor repo, as its a compiler issue. It seems at runtime the compiler is emitting an internal class for the generated code, so there is no error, but at design time it generates a public class. With a public class, and a public FooModel Model { get; set; } being generated, the error is expected, and can be seen in a regular C# class too:

image

The main issue here is the difference between designtime and runtime behaviour for Razor developers

alexrp commented 1 year ago

I believe there is a related issue in MVC views. Using dotnet new mvc and altering Views/Shared/Error.cshtml to:

@using mvc.Models

@model ErrorViewModel

And Models/ErrorViewModel.cs to:

namespace mvc.Models;

internal sealed class ErrorViewModel
{
}

I get:

image

This despite the fact that the generated page class is internal (dotnet build works fine).

migig commented 2 months ago

+1 Thank you to report this.

It is sad because like you say it is "best practice" to using internal in professional coding, but we must dirty the code just to keep this tool from making errors. This is very bad.

I hope this to be investigated and fixed - thanks guys!

lonix1 commented 2 months ago

Yep... We use public for everything because of this.

Also we've a number of RP-based libraries and it's a huge mess. If one uses internal then it must be internal "all the way down" - and since we can't use it on some stuff (i.e. PageModels), it means everything must be public. Really frustrating.

PS: don't spin your wheels, there are no workarounds (I've tried!) - just change everything to public for now.

chsienki commented 2 months ago

We're actively working on getting this fixed. Stay tuned!