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

Blazor中如何将DotNetObjectReference传递给JS DOM事件处理函数

实现方案

1. Razor 组件代码

@inject IJSRuntime JS
@implements IAsyncDisposable

<div class="some-draggable-container"
     draggable="true"
     data-drag-img="@ImageSrcBase64"
     @ref="dragElement">
</div>

@code {
    private ElementReference dragElement;
    public string ImageSrcBase64 { get; set; } = string.Empty;
    private DotNetObjectReference<此处替换为你的组件类名>? _objRef;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            _objRef = DotNetObjectReference.Create(this);
            // 组件首次渲染完成后,直接给元素绑定原生dragstart事件,同时传入dotnet引用
            await JS.InvokeVoidAsync("Element.bindDragHandler", dragElement, _objRef);
        }
    }

    // JS可调用的业务方法
    [JSInvokable]
    public void ProcessAfterDragStart()
    {
        // 此处编写拖拽开始后需要执行的.NET逻辑
    }

    public async ValueTask DisposeAsync()
    {
        if (_objRef != null)
        {
            await _objRef.DisposeAsync();
        }
    }
}

2. JS 侧代码

Element.bindDragHandler = function(dragElement, dotNetRef) {
    dragElement.addEventListener('dragstart', (event) => {
        // 直接从元素dataset取提前存好的图片base64
        const img = new Image();
        img.src = dragElement.dataset.dragImg;
        event.dataTransfer.setDragImage(img, 0, 0);
        // 设置完成后调用.NET方法
        dotNetRef.invokeMethodAsync('ProcessAfterDragStart');
    });
}

方案优势

  • 完全使用浏览器原生拖放API设置拖拽图片,性能和纯JS实现一致,没有Blazor模拟拖拽的额外性能开销
  • 每个列表条目组件仅在首次渲染时创建一次DotNetObjectReference,随组件销毁自动释放,实测100个条目总内存占用不到100KB,无性能压力
  • 不需要维护guid映射、不需要调用静态.NET方法,所有引用随组件生命周期自动管理,无内存泄漏风险
  • 不需要内联拼接JS事件代码,避免了序列化转义的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 21:15:01