dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
34.51k stars 9.75k forks source link

Multiple @page breaks css isolation in .net 8.0 blazor #55517

Closed brandonbvisi closed 1 week ago

brandonbvisi commented 2 weeks ago

Is there an existing issue for this?

Describe the bug

Using multiple @page on the Home.razor as seen below

@page "/"
@page "/{Test}"

<PageTitle>Home</PageTitle>
<h1>Hello, world!</h1>

Welcome to your new app.

@code
{
    [Parameter]
    public string? Test { get; set; }

}

Causes the "{Project}.styles.css" to be the App.Razor generated HTML. Not the appropriately generated CSS file when you hit the F12 developer tools in the browser. When viewing the sources and file, it will be as seen below. Which is not CSS but rather the App's HTML.

<!DOCTYPE html> <html lang="en"><head><meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <base href="/"> <link rel="stylesheet" href="bootstrap/bootstrap.min.css"> <link rel="stylesheet" href="app.css"> <link rel="stylesheet" href="BrokenBlazor.styles.css"> etc

The datatype of the parameter in the @page does not matter, I've changed it from nullable to non nullable, or an Int64, etc. (NOTE: It does have something to do with the datatype, but I did not place a constraint it in this code above -- update below)

Expected Behavior

The "Project.styles.css" should be CSS, not the App.Razor generated HTML. The parameter to be null/blank since it was not provided.

Steps To Reproduce

-Create new Blazor Web App with the standard defaults, only change: -Sever Rendering -Global -Add another @page to the top of Home.razor with a parameter. -Add a [Parameter] variable to take that paramter. -Run app -You will see the browser has no style and hit F12 to enter developer mode in the browser -Navigate to sources and look for your "{Project.}styles.css", see that is not valid css.

Exceptions (if any)

Standard exceptions that we always run into launching Blazor I think:

07:53:25:002 Microsoft.Hosting.Lifetime: Information: Now listening on: https://localhost:7056 07:53:25:002 Microsoft.Hosting.Lifetime: Information: Now listening on: http://localhost:5032 07:53:25:002 Microsoft.Hosting.Lifetime: Information: Application started. Press Ctrl+C to shut down. 07:53:25:002 Microsoft.Hosting.Lifetime: Information: Hosting environment: Development 07:53:25:002 Microsoft.Hosting.Lifetime: Information: Content root path: D:\BrokenBlazor\BrokenBlazor 07:53:25:275 Exception thrown: 'System.IO.IOException' in System.Net.Security.dll 07:53:25:275 Exception thrown: 'System.IO.IOException' in System.Private.CoreLib.dll 07:53:25:275 Exception thrown: 'System.IO.IOException' in System.Private.CoreLib.dll 07:53:25:275 Exception thrown: 'System.IO.IOException' in System.Net.Security.dll 07:53:25:275 Exception thrown: 'System.IO.IOException' in System.Private.CoreLib.dll 07:53:25:506 'BrokenBlazor.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.4\System.Net.WebSockets.dll'. 07:53:25:506 'BrokenBlazor.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.4\System.Threading.Tasks.dll'. 07:53:25:506 'BrokenBlazor.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.4\System.Net.NameResolution.dll'. 07:53:25:506 'BrokenBlazor.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\8.0.4\Microsoft.AspNetCore.Html.Abstractions.dll'. 07:53:25:506 'BrokenBlazor.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\8.0.4\Microsoft.AspNetCore.DataProtection.Extensions.dll'. 07:53:32:793 Exception thrown: 'System.IO.IOException' in System.Private.CoreLib.dll 07:53:32:793 Exception thrown: 'System.IO.IOException' in System.Private.CoreLib.dll 07:53:33:044 Exception thrown: 'System.IO.IOException' in System.Private.CoreLib.dll 07:53:33:044 Exception thrown: 'System.Net.WebSockets.WebSocketException' in System.Net.WebSockets.dll 07:53:33:044 Exception thrown: 'System.Net.WebSockets.WebSocketException' in System.Private.CoreLib.dll 07:53:33:131 The program '[42692] BrokenBlazor.exe' has exited with code 4294967295 (0xffffffff).

.NET Version

8.0.204

Anything else?

I noticed when this happens, the App.razor file will get multiple Initializes where one is the "/" index (or home page) and the other be the {PROJECT}.styles.css. Any other static linked file will also come through such as favicon.ico or favicon.png. Any 3rd party references to a RCL that generates and uses the _content folder will also not generate appropriately.

brandonbvisi commented 2 weeks ago

I assume with the parameter, it's taking all requests for static assets (project.styles.css, favicon.ico, etc) and passing that along to the page as the parameter rather than pulling from static files middleware? I would think the static files would happen first, then route. I will see if I can constrain it to a data type to bypass the static file paths. It seems like it starts multiple app.razors, and propagates through the system (routes.razor, etc) for all those static files once you put that @page "/{parameter}" in there on the same SignalIR connection. Seems every static file will run in parallel when this happens.

brandonbvisi commented 2 weeks ago

When I put a constraint on the parameter for a Guid then it works as the static files are likely a string... None the less, it might be nice if you guys produced a warning or something when someone puts a string parameter on the default route "/" .

@page "/"
@page "/{Test:Guid}"

<PageTitle>Home</PageTitle>
<h1>Hello, world!</h1>

Welcome to your new app.

@code
{
    [Parameter]
    public Guid? Test { get; set; }

}

This works.

brandonbvisi commented 2 weeks ago

Unfortunately trying to implement the constraint in my production code with a Guid constraint and it did not work.

@page "/authentication/login/{GUID:Guid}"

The NavigationManager.NavigateTo which passes a string (URL) to the page results in

"authentication/login/B72EEE27-35BD-42DC-B207-B043240C65F3"

12:57:05:016 Exception thrown: 'System.InvalidCastException' in Microsoft.AspNetCore.Components.dll 12:57:05:016 Unable to cast object of type 'System.String' to type 'System.Guid'.

And Blazor crashes.

javiercn commented 1 week ago

@brandonbvisi thanks for contacting us.

The problem is that your route is taking priority over the static files. Use {parameter:nonfile} to avoid that situation.

dotnet-policy-service[bot] commented 1 week ago

This issue has been resolved and has not had any activity for 1 day. It will be closed for housekeeping purposes.

See our Issue Management Policies for more information.