1

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

3
  • The code as posted should of course have worked. So the problem is somewhere else. Start by adding <p> @RendererInfo.IsInteractive </p> to the page. Check the console logs (including F12) for errors. Commented Jun 28 at 5:24
  • If that doesn't help, start a minimal reproducible example as a new project. Add elements from your app in steps until you can repro the problem. Commented Jun 28 at 5:25
  • Thank you @HenkHolterman for your replies! I had hoped I had missed something obvious that someone here could point out but alas. I did as you suggested albeit taking the opposite route of commenting everything in my program.cs (I suspected the issue would be in there) that wasn't in a clean project and sure enough everything worked. After uncommenting section by section I have pinpointed the culprit: 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. So thank you again! Commented Jun 30 at 14:47

2 Answers 2

0

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.

Sign up to request clarification or add additional context in comments.

Comments

0

The problem is with blazor server. It uses signalr internally. With adding an other signalr.client it conflict and click button stop working. For me webasesenly worked with signalr.client

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.