Blazor中如何从静态C#方法调用JavaScript函数?
如何在Blazor静态C#方法中调用JavaScript函数?
问题场景
在Razor文件中通过@inject IJSRuntime JSRuntime注入IJSRuntime后,后台代码中调用JS函数的逻辑运行正常:
private async Task DownloadPdf(bool foo) { await using var module = await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./create-pdf.js"); await module.InvokeVoidAsync("generatePdf", foo); }
但在独立的静态类中尝试调用JS函数时,IJSRuntime始终为null,代码示例:
public static class Bar { public static double Baz() { // 执行一些操作 // 调用JS函数 return baz; } }
解决方案
方法1:将IJSRuntime作为参数传入静态方法
静态类无法直接使用依赖注入,最稳妥的方式是从调用方(比如Razor组件或其后台类)把已注入的IJSRuntime实例传递给静态方法:
修改静态类方法:
public static class Bar { public static async Task<double> Baz(IJSRuntime jsRuntime) { // 执行前置操作 await using var module = await jsRuntime.InvokeAsync<IJSObjectReference>("import", "./create-pdf.js"); await module.InvokeVoidAsync("generatePdf", /* 传入所需参数 */); // 计算并返回结果 return baz; } }
在Razor后台调用时:
private async Task SomeComponentMethod() { double result = await Bar.Baz(JSRuntime); }
方法2:创建全局可访问的IJSRuntime实例(仅推荐WebAssembly场景)
如果需要在多处调用且不想每次传参,可以在启动时注册全局实例,但Blazor Server场景不建议使用(Server端每个用户会话有独立的IJSRuntime实例,全局存储会引发线程安全问题):
- 创建静态访问类:
public static class JSRuntimeAccessor { public static IJSRuntime Instance { get; set; } }
- 在Program.cs中初始化:
var builder = WebAssemblyHostBuilder.CreateDefault(args); // 其他配置代码... // 获取IJSRuntime实例并赋值 var jsRuntime = builder.Services.BuildServiceProvider().GetRequiredService<IJSRuntime>(); JSRuntimeAccessor.Instance = jsRuntime; await builder.Build().RunAsync();
- 在静态类中调用:
public static class Bar { public static async Task<double> Baz() { if (JSRuntimeAccessor.Instance == null) throw new InvalidOperationException("IJSRuntime未完成初始化"); await using var module = await JSRuntimeAccessor.Instance.InvokeAsync<IJSObjectReference>("import", "./create-pdf.js"); await module.InvokeVoidAsync("generatePdf", /* 传入所需参数 */); return baz; } }
内容的提问来源于stack exchange,提问作者Flippowitsch
相关产品推荐
相关产品推荐

