17

I try to implement a simple onclick event handler like this sample https://blazorfiddle.com/s/counter but not working in my solution. The event is only triggered at the run of the web page for unknown reasons.

The HTML page with Blazor component is well show but when I click on the button, nothing is happening.

I'm on VS 2019 .Net Core 3.0. ASP.NET MVC project

Counter.razor file:

@using Microsoft.AspNetCore.Components

<p>Current count: @currentCount</p>

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

@code {
    int currentCount = 0;

    private async Task IncrementCount()
    {
        await Task.Run(() => currentCount++);
    }
}

Index.cshtml:

@using WebApplication2.Views.Components

@{
    ViewData["Title"] = "Home Page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

@(await Html.RenderComponentAsync<Counter>(RenderMode.Server, new { }))

startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();

    services.AddHttpClient();
    services.AddRazorPages();
    services.AddServerSideBlazor();
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/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.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
        endpoints.MapBlazorHub();
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

The button in browser :

<button class="btn btn-primary" onclick="System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1+AsyncStateMachineBox`1[System.Threading.Tasks.VoidTaskResult,WebApplication2.Views.Components.Counter+<IncrementCount>d__2];">Click me</button>

Error in browser:

Bug in brower

Matze
  • 4,705
  • 6
  • 48
  • 63
micsp24
  • 171
  • 1
  • 1
  • 5

14 Answers14

27

This is the most popular question related to the problem: Blazor onclick events don't get triggered. Adding to the answers that resolved OP problem and were unable to resolve mine I would like to add that:

<script src="~/_framework/blazor.server.js"></script> need to be placed AFTER the component that declares the events, not in the <head /> tag. Possibly at the very bottom of the body tag of _Host.cshtml or your MVC View that needs Blazor components. If you don't do it, Blazor syntax will still work, the project WILL compile and most things WILL behave as expected but the events won't be triggered.

I just spent hours trying to figure that out.

Also if @onclick is not recognised as Blazor code in .razor files at all (this can happen especially in Component Libraries), make sure to add _Imports.razor at the very top of the project with the following content:

@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 Microsoft.JSInterop

If for some reason some of the namespaces can't be found, they can be added as nuget packages.

rvnlord
  • 3,088
  • 3
  • 18
  • 29
  • Pay particular attention to _Imports.razor at the very top of the project. I had this file in the Pages directory and everything would render but no interactivity worked. – Richard Davison Nov 20 '20 at 20:44
  • Thank you so much! I was moving using to the _imports and somehow onclick stopped working on some pages. I was missing some of the using statements in your list. – Michael Z. Dec 09 '20 at 08:29
  • I did not see any difference when moving the location of the blazor.server.js – Rob3C Apr 11 '21 at 23:45
17

I think your call to the onclick event is wrong, they changed the way you reference functions from

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

to

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

The @ is now in front of the @onclick and NOT in front of the function name.

Beltway
  • 364
  • 3
  • 13
David Masterson
  • 695
  • 4
  • 6
  • I tried already this. I think that is not correct because in the browser the button seems like: – micsp24 Oct 02 '19 at 11:48
  • the code behind will not compile if you are using the release version of .net 3.0 if you try the code as you have posted it will fail in blazor fiddle it yo change it to the new structure it compiles fine and works – David Masterson Oct 02 '19 at 12:33
  • Also if you follow the link to the blazor fiddle example you linked they have changed the structure to this between preview 7 to 3.0 release. And the only thing you say is not working is to onclick. – David Masterson Oct 02 '19 at 12:54
  • 1
    This answer should work (additionally the (); part is not needed) – Robert Perry Oct 25 '19 at 22:07
7

I had the exact same issue, but found the solution here.

https://stackoverflow.com/a/58444907/82197

You need to add a _Imports.razor file into your Components folder with the following using statements.

@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 Microsoft.JSInterop
YodasMyDad
  • 8,916
  • 24
  • 73
  • 119
4

It should be <button @onclick=IncrementCount

Peter Morris
  • 16,193
  • 8
  • 71
  • 124
3

Changing RenderMode.Static to RenderMode.Server will probably solve your problem since you use Server-Side Blazor. But as JohnB suggested, you should read the docs. Learn about the difference between Server-Side Blazor and Client-Side Blazor here: https://docs.microsoft.com/en-us/aspnet/core/blazor/hosting-models?view=aspnetcore-3.0

Pascal R.
  • 1,610
  • 17
  • 29
  • I changed several pieces of code (post is updated) and the render mode but the event is not triggered when I click on the button. I have now an error in browser. – micsp24 Oct 02 '19 at 09:29
3

In my case I added StaticFileOptions in Startup.cs like this (used this code in my mvc asp.core project)

app.UseStaticFiles(new StaticFileOptions()
{
   OnPrepareResponse = ctx =>
   {
       const int duration = 60 * 60 * 24;
       ctx.Context.Response.Headers[HeaderNames.CacheControl] = $"public,max-age={duration}";
   }
});

Then returned to

 app.UseStaticFiles();

and it started to work

DreamEvil
  • 151
  • 1
  • 13
  • 1
    This worked for me aswell! Was getting a "Failed to load resource _framework/blazor.server.js" in the browser console but once i reverted to just app.UseStaticFiles() everything worked. – Charalampos Hadjiantoniou Feb 08 '20 at 11:33
  • I had the same problem. Adding "if (path.EndsWith("blazor.server.js")) return;" to the "OnPrepareResponse" resolved the issue. – rBalzer Feb 21 '21 at 11:27
1

I just noticed are embedding this in a MVC application. You don't have the script tag to for blazor.server.js in the index.cshtml in you add

<script src="_framework/blazor.server.js"/>

at the bottom of the index.cshtml page this is what wires up the signalr to the server, which is needed for server side.

See Scott Hanselman doing exactly what you are trying to do.

David Masterson
  • 695
  • 4
  • 6
1

I had the same problem. The problem was running the app in Internet Explorer.

OnClick worked fine when I ran the app in Edge.

StuartV
  • 121
  • 1
  • 10
1

I had all my blazor components in a seperate "class library" project. Including @using Microsoft.AspNetCore.Components.Web in the component solved the issue.

Krika
  • 415
  • 7
  • 20
1

The solution for me ended up being quite a bit different than the other answers here. I was using Cloudflare CDN to help serve my Blazor Server app.

In the end, I needed to turn off 'HTML Minification' in Cloudflare to get my onclick events working again.

Turn this setting 'off' in Cloudflare in the 'Speed' settings section: enter image description here

For additional options for getting around the issue, please reference this blog post:

ASP.NET Core Blazor with SignalR breaks when used with Cloudflare's HTML minification by Tobias Zimmergren

I also ran into this same HTML Minification issue using Scully with Angular and Cloudflare.

Brendan Sluke
  • 469
  • 5
  • 9
1

I've just had a very strange case of this problem: this code wasn't triggered.

<div ... @onclick=@(_ => OnClick.InvokeAsync(EventArgs.Empty))></div>

The problem's root is still unclear, but the solution (or rather a workaround) was to replace lambda with a method name.

<div ... @onclick=OnClickHandler></div>

@code {
  private void OnClickHandler()
  {
    OnClick.InvokeAsync(EventArgs.Empty);
  }
}
Mike
  • 659
  • 6
  • 12
0

I was stuck all day with this problem and then discovered that was working just fine in Chrome. Therefore, I added http://localhost to my list of Intranet websites in the Windows 10 Control Panel / Internet Settings / Security page. This only needs to be done for developers running the app from Visual Studio.

Steven
  • 13
  • 4
0

I tried to figure out most of the solutions for Blazor inside the MVC app, some are incomplete so I’ve tried to prepare complex instructions which work for me. If you are working on Blazor inside an MVC app you have to do the following stuff.

Go to the _Layout.cshtml or index.html and in the bottom script section add

<script src="~/_framework/blazor.server.js"></script>

In the same file _Layout.cshtml or index.html in head tag section right after title or meta tags add:

<base href="/" />

or alternatively

<base href="~/"/> 

Create _Imports.razor file inside your Blazor components directory and add to it following using statements:

@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 Microsoft.JSInterop

Alternatively, you can add these statements directly at the beginning of your component file.

Use onclick as follow:

if you want to pass parameters:

@onclick="(()=>YourEvent(yourParams))"

or simply if you just want to call:

@onclick="YourEvent"
ElConrado
  • 1,282
  • 2
  • 18
  • 37
-1

Try add @ at onclick like this

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

Thanks Joon

Joon w K
  • 699
  • 1
  • 5
  • 23