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

Blazor中C#代码移除元素仅生效一次且连接重置问题排查

问题描述

尝试通过单次按钮点击移除div并修改计数器,代码实现如下:

<button @onclick="() => RemoveDocument(className)" class="close-button inner-div">X</button>
private async void RemoveDocument(string className)
{
    AmountOfDocs--;
    await JSRuntime.InvokeVoidAsync("removeDiv", className);
}
function removeDiv(elName) {
    var element = document.getElementById(elName);      
    element.remove();
}

执行后div确实从DOM中被移除,但出现以下错误,且后续所有按钮无法点击:

blazor.server.js:1  [2023-10-17T14:58:52.607Z] Error: There was an error applying batch 11.

blazor.server.js:1  Uncaught (in promise) TypeError: Cannot read properties of null (reading 'removeChild')
    at H (blazor.server.js:1:17228)
    at ie.applyEdits (blazor.server.js:1:21401)
    at ie.updateComponent (blazor.server.js:1:20631)
    at blazor.server.js:1:115262
    at Pn.processBatch (blazor.server.js:1:115634)
    at kt.<anonymous> (blazor.server.js:1:129816)
    at blazor.server.js:1:72077
    at Array.forEach (<anonymous>)
    at kt._invokeClientMethod (blazor.server.js:1:72063)
    at kt._processIncomingData (blazor.server.js:1:70105)

[2023-10-17T14:58:52.655Z] Error: System.AggregateException: One or more errors occurred. (TypeError: Cannot read properties of null (reading 'removeChild'))
 ---&gt; System.InvalidOperationException: TypeError: Cannot read properties of null (reading 'removeChild')
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.InvokeRenderCompletedCallsAfterUpdateDisplayTask(Task updateDisplayTask, Int32[] updatedComponents)
   --- End of inner exception stack trace ---
log @ blazor.server.js:1
tr @ blazor.server.js:1
(anonymous) @ blazor.server.js:1
(anonymous) @ blazor.server.js:1
_invokeClientMethod @ blazor.server.js:1
_processIncomingData @ blazor.server.js:1
connection.onreceive @ blazor.server.js:1
o.onmessage @ blazor.server.js:1
blazor.server.js:1 [2023-10-17T14:58:52.656Z] Information: Connection disconnected.
问题原因

Blazor Server基于服务器端渲染+SignalR双向通信机制,渲染引擎会维护一份客户端DOM的虚拟映射副本。用JS直接从真实DOM中删除元素后,Blazor的虚拟DOM仍认为该元素存在,后续修改AmountOfDocs触发重新渲染时,引擎尝试操作已被删除的真实DOM节点,就会抛出Cannot read properties of null错误,最终导致SignalR连接断开,所有依赖Blazor交互的按钮失效。

解决方案

放弃JS直接操作DOM的方式,改用Blazor原生的组件渲染逻辑控制元素移除:

  1. 将需要移除的div包装为组件,通过绑定数据源的方式用foreach循环渲染
  2. 点击按钮时直接从数据源中移除对应项,Blazor会自动同步更新真实DOM,同时保证虚拟DOM与真实DOM的一致性

示例代码:

@foreach(var doc in Documents)
{
    <div id="@doc.ClassName">
        <!-- 自定义div内容 -->
        <button @onclick="() => RemoveDocument(doc)">X</button>
    </div>
}
<p>文档数量: @Documents.Count</p>
private List<DocumentModel> Documents = new List<DocumentModel>();

private void RemoveDocument(DocumentModel doc)
{
    Documents.Remove(doc);
    // 无需调用JS,Blazor会自动处理DOM移除
}

// 自定义文档模型
public class DocumentModel
{
    public string ClassName { get; set; }
    // 其他业务属性
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 12:35:27