Blazor通过JS互操作调用非静态方法找不到对应方法如何解决
Blazor JS互操作调用实例方法报错问题修复方案
核心错误原因
你混淆了Blazor两种JS互调场景的规则:
- 静态.NET方法调用:使用全局
DotNet.invokeMethod/invokeMethodAsync接口,需要传入程序集名、方法标识,要求目标方法带static修饰符 - 组件实例.NET方法调用:使用提前创建的
DotNetObjectReference实例调用对应接口,不需要传程序集名,目标方法不需要static修饰符
你的代码存在两个关键问题:
- 已经通过
DotNetObjectReference.Create(this)创建了组件实例引用并传给JS,但调用时传入的是全局window.DotNet对象而非存储的组件实例引用 - 调用实例方法时错误传入了程序集名参数,不符合实例方法调用规则
修复步骤
1. 优化Blazor组件代码
将方法返回值从async void改为async Task避免异步异常丢失,新增销毁逻辑避免内存泄漏:
protected override Task OnInitializedAsync() { jsToDotNetBridgeReference = DotNetObjectReference.Create(this); js.InvokeVoidAsync("SetDotNetReference", jsToDotNetBridgeReference); return base.OnInitializedAsync(); } [JSInvokableAttribute("INIT_COMPLIANCE")] public async Task InitComplianceComponent(string token) { id_token = token; Console.WriteLine(token); await GetData(); } // 新增:组件销毁时释放引用 public void Dispose() { jsToDotNetBridgeReference?.Dispose(); }
2. 修正BlazorInterop.js逻辑
补全全局变量存储组件实例,调整调用逻辑:
// 新增全局变量存储Blazor组件实例 let dotNetComponentRef = null; // 接收Blazor传过来的组件实例 SetDotNetReference = function (ref) { dotNetComponentRef = ref; } InitComplianceComponent = function (token) { // 直接用组件实例调用,不需要传程序集名,推荐用异步调用避免死锁 dotNetComponentRef.invokeMethodAsync("INIT_COMPLIANCE", token); }
3. 修正业务JS调用逻辑
不需要传入window.DotNet,直接传token即可:
self.addNewCompliance = function () { const url = someurl; var resource = window.authContext.getResourceForEndpoint(url); window.authContext.acquireToken(resource, function (error, token) { // Handle ADAL Error if (error || !token) { console.log('ADAL Error Occurred: ' + error); return; } else { Blazor.start().then(() => { window.InitComplianceComponent(token); }) } }); }
内容的提问来源于stack exchange,提问作者curious_debugger
相关产品推荐
相关产品推荐

