You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级Visual Studio后,.Net调用JavaScript代码失效问题

问题:VS2022升级至v17.8.2后Blazor组件JS调用失败

原本在Visual Studio 2022 v17.7.6及其他电脑上可正常运行的Blazor组件代码,升级VS至v17.8.2后抛出JS函数未找到的错误,使用.NET Core 6环境,代码位于页面组件中。

后端C#代码

[Inject] IJSRuntime? JSRT { get; set; }
DotNetObjectReference<GraphicalUngrouped>? objectReference;

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender) await BundleAndSendDotNetHelper();
}

private async Task BundleAndSendDotNetHelper()
{
    objectReference = DotNetObjectReference.Create(this);
    if (JSRT != null)
    {
        await JSRT.InvokeAsync<string>("SetDotNetHelper", objectReference);
    }
}

Razor页面代码

<script>
    function SetDotNetHelper(dotNetHelper) {
        window.dotNetHelper = dotNetHelper;
    }
</script>

抛出错误

Unhandled exception rendering component: Could not find 'SetDotNetHelper' ('SetDotNetHelper' was undefined).

Error: Could not find 'SetDotNetHelper' ('SetDotNetHelper' was undefined).
    at https://localhost:7211/_framework/blazor.webassembly.js:1:328
    at Array.forEach (<anonymous>)...

问题原因

VS2022 v17.8.x版本对Blazor WebAssembly的组件内脚本加载机制做了调整,组件内嵌的<script>标签不再保证在组件首次渲染(firstRender=true)前完成全局注入。当OnAfterRenderAsync执行时,脚本函数还未注册到window对象,导致调用失败。

解决建议

方案一:将脚本移至全局入口文件

把组件内的<script>内容移到wwwroot/index.html的<body>末尾,确保脚本在Blazor应用初始化前加载完成:

<!-- wwwroot/index.html -->
<body>
    <!-- 其他内容 -->
    <script src="_framework/blazor.webassembly.js"></script>
    <script>
        function SetDotNetHelper(dotNetHelper) {
            window.dotNetHelper = dotNetHelper;
        }
    </script>
</body>

方案二:使用ES模块加载脚本

将脚本单独存入wwwroot/js/helpers.js文件,通过IJSRuntime异步加载模块:

// wwwroot/js/helpers.js
export function SetDotNetHelper(dotNetHelper) {
    window.dotNetHelper = dotNetHelper;
}

修改后端C#代码,引入模块加载逻辑:

[Inject] IJSRuntime? JSRT { get; set; }
DotNetObjectReference<GraphicalUngrouped>? objectReference;
private IJSObjectReference? module;

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        module = await JSRT!.InvokeAsync<IJSObjectReference>("import", "./js/helpers.js");
        objectReference = DotNetObjectReference.Create(this);
        await module.InvokeVoidAsync("SetDotNetHelper", objectReference);
    }
}

public async ValueTask DisposeAsync()
{
    if (module != null)
    {
        await module.DisposeAsync();
    }
    objectReference?.Dispose();
}

方案三:临时延迟调用(不推荐)

在OnAfterRenderAsync中添加小延迟,等待脚本加载完成(仅应急使用,不适合生产环境):

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        await Task.Delay(100);
        await BundleAndSendDotNetHelper();
    }
}

内容的提问来源于stack exchange,提问作者Slugsie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 07:14:54