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
35.36k stars 9.99k forks source link

.NET 8 Blazor Error 404 after upgrading from .NET 6 #52710

Closed rzechu closed 10 months ago

rzechu commented 10 months ago

Is there an existing issue for this?

Describe the bug

I have try to upgrade my Blazor Server App from .NET 6 to .NET 8 i guess I followed instructions from: https://learn.microsoft.com/en-us/aspnet/core/migration/70-80?view=aspnetcore-8.0&tabs=visual-studio#adopt-all-blazor-web-app-conventions

Comparing my after changes files with files from new created Blazor Web App project and files from: https://github.com/danroth27/Net8BlazorServer/tree/main

I am using Shared project (due to using project for Native)

It used to work in .NET 6

After running application I have no runtime/compilation errors - just error 404 after app startup I am using Mudblazor too but I doubt problem is here. I guess its even before app fully startup.

App.razor

@inject IHostEnvironment Env
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <base href="~/" />
    <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet" />
    <link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" />
    <HeadOutlet @rendermode="InteractiveServer" />

</head>
<body>
    <Routes @rendermode="InteractiveServer" /> 

    <div id="blazor-error-ui">
        @if (Env.IsDevelopment())
        {
        <text>
        An unhandled exception has occurred. See browser dev tools for details.
        </text>
        }
        else
        {
        <text>
        An error has occurred. This app may no longer respond until reloaded.
        </text>
        }
        <a href="" class="reload">Reload</a>
        <a class="dismiss">🗙</a>
    </div>
        <script src="_framework/blazor.web.js"></script>
        <script src="_content/MudBlazor/MudBlazor.min.js"></script>
</body>
</html>

_Imports.razor

@using System.Net.Http
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop

@using MyApp.Web
@using MyApp.Shared
@using MyApp.Shared.Pages
@using MyApp.Shared.Shared
@using MyApp.Shared.Services

@using MudBlazor

Routes.razor

<Router AppAssembly="@typeof(App).Assembly" AdditionalAssemblies="new[] {typeof(Shared.Shared.MainLayout).Assembly}">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
        <FocusOnNavigate RouteData="@routeData" Selector="h1" />
    </Found>
    <NotFound>
        <PageTitle>Not found</PageTitle>
        <LayoutView Layout="@typeof(MainLayout)">
            <p role="alert">Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

Program.cs

using MyApp.Shared.Data;
using MyApp.Shared.Services;
using MyApp.Web;
using Microsoft.AspNetCore.Hosting.StaticWebAssets;
using MudBlazor.Services;

var builder = WebApplication.CreateBuilder(args);

StaticWebAssetsLoader.UseStaticWebAssets(builder.Environment, builder.Configuration);

var appSettings = builder.Configuration.GetSection(nameof(WebSettings)).Get<WebSettings>();
string BASE_ADRESS = appSettings?.WebApiUrl ?? throw new ArgumentNullException("webapiUrl");

Console.WriteLine($"web console {BASE_ADRESS ?? "empty"}");
System.Diagnostics.Debug.WriteLine($"web diag {BASE_ADRESS ?? "empty"}");

builder.Services.AddHttpClient(MyApp.Shared.Conts.HTTP_CLIENT, options =>
{
    options.BaseAddress = new Uri(BASE_ADRESS!);
    options.DefaultRequestHeaders.Add("Accept", "application/json");
});

//builder.Services.AddRazorPages();
builder.Services.AddRazorComponents().AddInteractiveServerComponents();
builder.Services.AddSingleton<IDataService, DataService>();
builder.Services.AddSingleton<PromotionStateContainer>();
builder.Services.AddMudServices();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAntiforgery();

app.MapRazorComponents<MyApp.Web.App>().AddInteractiveServerRenderMode();

app.Run();

I have tried add to Program.cs app.UseStatusCodePagesWithRedirects("/404"); And _404.razor

@page "/404"
<h3>Show me 404</h3>
@code {
}

To both MyApp.Web.Pages MyApp.Shared.Pages

It automatically makes redtrection to http://localhost:xxxx/404 but it doesn't shows any page too just

This page isn’t workinglocalhost redirected you too many times.
[Try clearing your cookies](https://support.google.com/chrome?p=rl_error&hl=en-GB).
ERR_TOO_MANY_REDIRECTS

Expected Behavior

Page is running or atleast run and throwing any error in compliation/runtime

Steps To Reproduce

No response

Exceptions (if any)

No response

.NET Version

8.0

Anything else?

No response

rzechu commented 10 months ago

Ok I finally resolved problem. There was additional uneccesary ASP.NETCore nuget packages in my projects

I removed all and now it looks that: MyApp.Shared.csproj

...
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="8.0.0" />
    <PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
    <PackageReference Include="MudBlazor" Version="6.8.0" />
  </ItemGroup>

...

MyApp.Web.csproj

...

  <ItemGroup>
    <Compile Remove="Shared\**" />
    <Content Remove="Shared\**" />
    <EmbeddedResource Remove="Shared\**" />
    <None Remove="Shared\**" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\MyApp.Shared\MyApp.Shared.csproj" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="8.0.0" />
    <PackageReference Include="MudBlazor" Version="6.8.0" />
  </ItemGroup>
...

I moved my data for both projects from Pages and Shared to Components\Pages Components\Shared Components\App.razor Components\Route.razor

Changed Route.razor to following (check 1 line )

<Router AppAssembly="@typeof(App).Assembly" AdditionalAssemblies="new[] {typeof(MyApp.Shared.Components.Shared.MainLayout).Assembly, typeof(Program).Assembly }">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
        <FocusOnNavigate RouteData="@routeData" Selector="h1" />
    </Found>
    <NotFound>
        <PageTitle>Not found</PageTitle>
        <LayoutView Layout="@typeof(MainLayout)">
            <p role="alert">Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

And in Program.cs i changed

app.MapRazorComponents<MyApp.Web.Components.App>()
    .AddInteractiveServerRenderMode()

To

app.MapRazorComponents<MyApp.Web.Components.App>()
    .AddInteractiveServerRenderMode()
    .AddAdditionalAssemblies(new System.Reflection.Assembly[] { typeof(MyApp.Shared.Components.Shared.MainLayout).Assembly });

Looks like everything even MudBlazor working corectly now!

erikthysell commented 10 months ago

@rzechu Do you have any idea of what precisely made it work? (I have the same issue with blazor wasm/server hosted that I am trying to upgrade) (HTTP GET / responded 404 in 74.9575 ms)

rzechu commented 10 months ago

@erikthysell I posted my thought above.

  1. Try compare files between / clean new generated project and posted repo and your project.
  2. Move App.Razor / Routers.razor and your Pages folder one level deeper to Components folder

Server/server-side: Interactive server-side rendering (interactive SSR) of a Blazor Web App. The Program file is Program.cs of the server project. Blazor script start configuration is found in the App component (Components/App.razor). Only routable Interactive Server render mode components with an @page directive are placed in the Components/Pages folder. Non-routable shared components are placed in the server project's Components folder. Create custom folders based on component functionality as needed. https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/routing?view=aspnetcore-8.0

Check Program.cs my two last quotes from previous post and Routes.razor

javiercn commented 10 months ago

@rzechu seems you were able to resolve the issues.

@erikthysell if you are running into issues, please file a separate issue with concrete details, as otherwise we'll lose track of it, and details from different issues get confused.

gshock commented 9 months ago

Hi all, add this to your program.cs (in a Blazor Web App) so that the @page="/" in the Shared library is found at compile time. "Map Razor Components" If your app is not working, check if it's a 404 or 500 error.

app.MapRazorComponents() .AddAdditionalAssemblies(new System.Reflection.Assembly[] { typeof(MyApp.Shared.Components.Shared.MainLayout).Assembly });

This is among @rzechu list of changes.

rzechu commented 9 months ago

Hi all, add this to your program.cs (in a Blazor Web App) so that the @page="/" in the Shared library is found at compile time. "Map Razor Components" If your app is not working, check if it's a 404 or 500 error.

app.MapRazorComponents() .AddAdditionalAssemblies(new System.Reflection.Assembly[] { typeof(MyApp.Shared.Components.Shared.MainLayout).Assembly });

This is among @rzechu list of changes.

Thank you. I posted my solution 3posts above and the thing you mentioned is included in last one quote