I need some help. This is the first time I'm building a Blazor app and I've been trying to get an @onclick
working on a button in my .NET 9 Blazor Server app and I just can't get it to work.
I've found countless of answers saying I need to set the render mode, which I hadn't but sadly that didn't help at all. I tried both setting it for the entire app in App.razor
(<Routes @rendermode="InteractiveServer" />
) and setting it in my page (@rendermode InteractiveServer
).
I checked the program.cs and it does have the .AddInteractiveServerComponents()
on both the AddRazorComponents()
and the MapRazorComponents<App>()
as it should be:
using BoatPlannerAI.Web.Components;
using Microsoft.Azure.Cosmos;
using System.Globalization;
using Microsoft.Extensions.Options;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
var cosmosConfig = builder.Configuration.GetSection("CosmosDb");
var account = cosmosConfig["Account"];
var key = cosmosConfig["Key"];
var databaseName = cosmosConfig["DatabaseName"];
if (string.IsNullOrWhiteSpace(databaseName))
throw new InvalidOperationException("CosmosDb:DatabaseName configuration is missing or empty.");
builder.Services.AddSingleton(s => new CosmosClient(account, key));
builder.Services.AddSingleton(_ => databaseName);
// Add localization services
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
var supportedCultures = new[] { new CultureInfo("en"), new CultureInfo("nl") };
builder.Services.Configure<RequestLocalizationOptions>(options =>
{
options.DefaultRequestCulture = new Microsoft.AspNetCore.Localization.RequestCulture("nl");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseAntiforgery();
app.MapStaticAssets();
// Redirect root '/' to '/nl' on the server side
app.Use(async (context, next) =>
{
if (context.Request.Path == "/")
{
context.Response.Redirect("/nl", permanent: false);
return;
}
await next();
});
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
// Configure localization middleware
var locOptions = app.Services.GetRequiredService<IOptions<RequestLocalizationOptions>>();
app.UseRequestLocalization(locOptions.Value);
// Set culture based on first URL segment
app.Use(async (context, next) =>
{
var path = context.Request.Path.Value;
if (!string.IsNullOrEmpty(path))
{
var segments = path.Split('/', StringSplitOptions.RemoveEmptyEntries);
if (segments.Length > 0)
{
var lang = segments[0];
var supported = new[] { "en", "nl" };
if (supported.Contains(lang))
{
var culture = new CultureInfo(lang);
CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture;
}
}
}
await next();
});
app.Run();
I also checked my _Imports.razor
, it is in the correct location and has all the using
I'd expect:
@using System.Net.Http
@using System.Net.Http.Json
@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 BoatPlannerAI.Web
@using BoatPlannerAI.Web.Components
As I said, I tried setting the render mode for the entire app using:
<!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="@Assets["lib/bootstrap/dist/css/bootstrap.min.css"]" />
<link rel="stylesheet" href="@Assets["app.css"]" />
<ImportMap />
<link rel="icon" type="image/png" href="favicon.png" />
<HeadOutlet />
</head>
<body>
<Routes @rendermode="InteractiveServer" />
<script src="_framework/blazor.web.js"></script>
</body>
</html>
And I also tried setting it in the page:
@page "/{lang}/buttontest"
@rendermode InteractiveServer
@using Microsoft.Extensions.Localization
@inject IStringLocalizer<ButtonTest> L
@code {
[Parameter] public string? lang { get; set; }
private int buttonClickedCount = 0;
private void ButtonClicked()
{
Console.WriteLine("Button clicked");
buttonClickedCount++;
}
}
Test the button <button @onclick="ButtonClicked" >Click me</button>
<p>Button clicked: @buttonClickedCount</p>
But nothing works. This the onclick
is never even triggered if you ask me.
What am I missing here? Any help would be greatly appreciated!
Thanks,
elloco
So I figured it out. Thank you @HenkHolterman for your suggestion in the comments, that led to me finding the issue.
In my program.cs I had this line:
`builder.Services.AddSingleton(_ => databaseName);`
Turns out Blazor doesn't like it when you register strings as Singletons... I removed that line and it works fine now.
Cursor thought it would be useful to register the DB name as a singleton so it could easily be used throughout the application. And I failed to catch that.