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.79k stars 9.83k forks source link

Adding WebAssembly to Blazor Web App template fails: dotnet.js not found #56013

Closed EmreSURK closed 4 weeks ago

EmreSURK commented 1 month ago

Is there an existing issue for this?

Describe the bug

On MacOS and Rider, I create a new Blazor project by selecting Blazor Web App by using dotnet8.0. My target is, keeping the same pages Server Rendered and make Counter page' rendermode is InteractiveWebAssembly

The problem is: After I made these changes, the "Click Me" button is not working. The number does not change when I click.

When I check the console of browser, I saw an error message:

Failed to load resource: the server responded with a status of 404 (Not Found) blazor.web.js:1 Uncaught (in promise) Error: Failed to start platform. Reason: TypeError: Failed to fetch dynamically imported module: http://localhost:5216/_framework/dotnet.js at ei (blazor.web.js:1:164030)

Screenshot 2024-06-01 at 11 54 38 PM

I created a brand new project and made these changes:

Program.cs, 11th line, Old:

builder.Services.AddRazorComponents().AddInteractiveServerComponents();

Program.cs, 11th line, New: builder.Services.AddRazorComponents().AddInteractiveServerComponents().AddInteractiveWebAssemblyComponents();

Program.cs, 58th line, Old: app.MapRazorComponents<App>().AddInteractiveServerRenderMode();

Program.cs, 58th line, New: app.MapRazorComponents<App>().AddInteractiveServerRenderMode().AddInteractiveWebAssemblyRenderMode();

I added this line to Counter.razor: @rendermode InteractiveWebAssembly

Program.cs:

using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using BlazorApp2.Components;
using BlazorApp2.Components.Account;
using BlazorApp2.Data;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorComponents().AddInteractiveServerComponents().AddInteractiveWebAssemblyComponents();

builder.Services.AddCascadingAuthenticationState();
builder.Services.AddScoped<IdentityUserAccessor>();
builder.Services.AddScoped<IdentityRedirectManager>();
builder.Services.AddScoped<AuthenticationStateProvider, IdentityRevalidatingAuthenticationStateProvider>();

builder.Services.AddAuthentication(options =>
    {
        options.DefaultScheme = IdentityConstants.ApplicationScheme;
        options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
    })
    .AddIdentityCookies();

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlite(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddIdentityCore<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddSignInManager()
    .AddDefaultTokenProviders();

builder.Services.AddSingleton<IEmailSender<ApplicationUser>, IdentityNoOpEmailSender>();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Error", createScopeForErrors: true);
    // 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.MapBlazorHub("/");

app.MapRazorComponents<App>().AddInteractiveServerRenderMode().AddInteractiveWebAssemblyRenderMode();

// Add additional endpoints required by the Identity /Account Razor components.
app.MapAdditionalIdentityEndpoints();

app.Run();

Counter.cs ( Please see second line )

@page "/counter"
@rendermode InteractiveWebAssembly

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }

}

Expected Behavior

I expect that Click Me button is working and there is no 404 error for dotnet.js

Steps To Reproduce

Minimalistic project: https://github.com/EmreSURK/blazor_webasm_404 You can run the minimalistic project and check Counter page. Press the "Click Me" button and observer Current Count label. Also, please check devtools -> console for the 404 error.

Or, you can try it yourself by following these steps:

  1. Create a Blazor Web App.
  2. Make these changes: Program.cs, 11th line, Old: builder.Services.AddRazorComponents().AddInteractiveServerComponents(); Program.cs, 11th line, New: builder.Services.AddRazorComponents().AddInteractiveServerComponents().AddInteractiveWebAssemblyComponents();

Program.cs, 58th line, Old: app.MapRazorComponents<App>().AddInteractiveServerRenderMode(); Program.cs, 58th line, New: app.MapRazorComponents<App>().AddInteractiveServerRenderMode().AddInteractiveWebAssemblyRenderMode();

Add this line to Counter.razor: @rendermode InteractiveWebAssembly

  1. Run the project,
  2. Visit the Counter page
  3. Press the "Click Me" button
  4. Check the Current count number.

Exceptions (if any)

Screenshot 2024-06-01 at 11 54 38 PM

.NET Version

8.0.200

Anything else?

I didnt add/change base url or anything similar. I added these packages:

<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.6" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.6" />
<PackageReference Include="Microsoft.JSInterop.WebAssembly" Version="8.0.6" />
javiercn commented 1 month ago

@EmreSURK thanks for contacting us.

Adding webassembly to the application requires a few more steps. We suggest that you start from the template by selecting new blazor web app with webassembly interactivity and that will setup things for what you are trying to do.

Among other things, you need 2 projects when running webassembly (similar to webassembly hosted in previous versions) as the webassembly bits are their own separate process on the client.

Any component or code that needs to run on webassembly needs to be part of this project, as otherwise it won't be downloaded to the client.

EmreSURK commented 1 month ago

hi @javiercn Thank you for informing me.

As I see, my target is not common and not feasible.

dotnet-policy-service[bot] commented 4 weeks 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.