The assembly does not contain a public invokable method with [JSInvokableAttribute]
A

4

14

We use Blazor WebAssembly and I want to call an non-static method in my Index.razor-File by JavaScript.

JavaScript:

(function () {

    // keydown event
    window.addEventListener("keydown", function (e) {
        DotNet.invokeMethodAsync('MyBlazorWebAssemblyApp.Client', 'MyMethod');
    });
})();

Index.razor:

@page "/"
@inject HttpClient Http

@code {
    
    // [...]
    
    [JSInvokable]
    public async Task MyMethod()
    {
        var lResponse = await Http.GetFromJsonAsync<object>("Controller/Action");
    }
}

When I execute the code by an keydown, then the developer tools in Microsoft Edge shows me the following error:

blazor.webassembly.js:1 System.ArgumentException: The assembly 'MyBlazorWebAssemblyApp.Client' does not contain a public invokable method with [JSInvokableAttribute("MyMethod")].

When I replace the attribute [JSInvokable] by [JSInvokableAttribute("MyMethod")] then the same error appears.

How can I fix this problem?

Auteur answered 17/7, 2020 at 12:57 Comment(3)
learn.microsoft.com/en-us/aspnet/core/blazor/…Remscheid
What happens if you just use MyBlazorWebAssemblyApp i.e. remove the .Client from the app assembly argument?Doradorado
@Mark3308: System.ArgumentException: There is no loaded assembly with the name 'MyBlazorWebAssemblyApp'.Auteur
A
22

Got it working now by my self. Here is the code:

JavaScript:

var GLOBAL = {};
GLOBAL.DotNetReference = null;
GLOBAL.SetDotnetReference = function (pDotNetReference) {
    GLOBAL.DotNetReference = pDotNetReference;
};

(function () {

    // keydown event
    window.addEventListener("keydown", function (e) {
        GLOBAL.DotNetReference.invokeMethodAsync('MyMethod');
    });
})();

Index.razor:

@page "/"
@inject HttpClient Http

@code {
    
    protected override async Task OnInitializedAsync()
    {
        var lDotNetReference = DotNetObjectReference.Create(this);
        JSRuntime.InvokeVoidAsync("GLOBAL.SetDotnetReference", lDotNetReference);
    }
    
    // [...]
    
    [JSInvokable("MyMethod")]
    public async Task MyMethod()
    {
        var lResponse = await Http.GetFromJsonAsync<object>("Controller/Action");
    }
}
Auteur answered 20/7, 2020 at 9:7 Comment(5)
One question here, how does GLOBAL.SetDotnetReference get dotnetreference ?Kiyokokiyoshi
@KshitijAnilRangari it's created in the OnInitializedAsyncBuffybuford
@Auteur but your code has a problem when use in Foreach, already call last item.Ule
Excellent Question and Answer - this also works within OnAfterRenderAsync, and was great for me since I also needed it for a non static method in a simple single page application :).Rianna
Thanks, this is the only thing that's worked (besides making the method static) after hours of trying. However I have another problem now. My Blazor code that's called from JS is on a separate razor page/component. When I navigate to it, I get this error: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] Unhandled exception rendering component: Could not find 'GLOBAL.SetDotnetReference' ('GLOBAL' was undefined). Then if I refresh the page, the error goes away and it works. How can I fix this?Spoonerism
D
2

If you check out the Microsoft documentation at the following link:

https://learn.microsoft.com/en-gb/aspnet/core/blazor/call-dotnet-from-javascript?view=aspnetcore-3.1#instance-method-call

This differs from your example in the following ways:

Your JavaScript appears to be trying to call a static .NET method.

Your C# code is not a static method.

Doradorado answered 20/7, 2020 at 10:4 Comment(0)
U
2

You must mention <<Namespace>>.<<TypeName>>.<<MethodName>>

Important: C# Method must static

window.addEventListener("keydown", async function (e) {
        await DotNet.invokeMethodAsync('MyBlazorWebAssemblyApp.Client', 'MyMethod');
});

#40110 issue

Ule answered 8/10, 2022 at 18:31 Comment(0)
A
0

your method must be static

 [JSInvokable("MyMethod")]
public static async Task MyMethod()
{
    var lResponse = await Http.GetFromJsonAsync<object>("Controller/Action");
}
Almanac answered 27/7 at 19:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.