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

Blazor实现PDF/PNG/JPG文件拖拽上传并打印文件名求助

Blazor实现文件拖拽/选择功能的正确姿势

先改Razor模板

把原来的硬编码ID换成Blazor的组件引用和内置事件,避免直接操作DOM踩坑:

<div @ref="dropZoneRef" 
     class="bg-white flex flex-col items-center justify-center py-20 border border-slate-200 rounded-md relative"
     @ondragenter="HandleDragEnter"
     @ondragover="HandleDragOver"
     @ondragleave="HandleDragLeave"
     @ondrop="HandleDrop">
    <img src="\assets\AIDocReader\icons\file-upload-input.svg" alt="Icon for upload file" class="w-8">
    <p>Drag & drop or <span class="text-tertiary">browse</span> your files</p>
    <input type="file" 
           accept=".pdf, .png, .jpg" 
           class="absolute top-0 left-0 h-full w-full cursor-pointer opacity-0"
           @onchange="HandleFileSelect" />
    <p>@selectedFileName</p>
</div>

写C#逻辑

在组件的@code块里处理所有事件,用Blazor自带的API,少写原生JS:

@inject IJSRuntime JSRuntime

<!-- 上面的模板代码 -->

@code {
    // 引用拖拽区域的DOM元素
    private ElementReference dropZoneRef;
    // 用来显示选中的文件名
    private string selectedFileName = string.Empty;

    // 处理点击选择文件的情况
    private void HandleFileSelect(ChangeEventArgs e)
    {
        var files = e.Value as IReadOnlyList<IBrowserFile>;
        if (files?.Count > 0)
        {
            selectedFileName = files[0].Name;
            Console.WriteLine($"选中的文件:{selectedFileName}");
        }
    }

    // 拖拽进入区域时,添加高亮样式
    private void HandleDragEnter(DragEventArgs e)
    {
        e.PreventDefault();
        // 通过JS互操作给元素加类
        _ = JSRuntime.InvokeVoidAsync("addClass", dropZoneRef, "bg-background");
    }

    // 拖拽悬浮时,必须阻止默认行为,否则浏览器会打开文件
    private void HandleDragOver(DragEventArgs e)
    {
        e.PreventDefault();
    }

    // 拖拽离开区域,移除高亮样式
    private void HandleDragLeave(DragEventArgs e)
    {
        e.PreventDefault();
        _ = JSRuntime.InvokeVoidAsync("removeClass", dropZoneRef, "bg-background");
    }

    // 拖拽放下时处理文件
    private async Task HandleDrop(DragEventArgs e)
    {
        e.PreventDefault();
        _ = JSRuntime.InvokeVoidAsync("removeClass", dropZoneRef, "bg-background");

        // 通过JS获取拖拽的文件列表
        var files = await JSRuntime.InvokeAsync<IReadOnlyList<IBrowserFile>>(
            "getDroppedFiles", e.DataTransfer);
        
        if (files?.Count > 0)
        {
            selectedFileName = files[0].Name;
            Console.WriteLine($"拖拽的文件:{selectedFileName}");
        }
    }
}

加少量辅助JS

在wwwroot下新建file-helpers.js,写几个简单的工具函数:

// 给元素添加CSS类
window.addClass = function(element, className) {
    element.classList.add(className);
}

// 移除元素的CSS类
window.removeClass = function(element, className) {
    element.classList.remove(className);
}

// 提取拖拽的文件信息
window.getDroppedFiles = function(dataTransfer) {
    return Array.from(dataTransfer.files).map(file => ({
        Name: file.name,
        Size: file.size,
        ContentType: file.type
    }));
}

然后在入口文件里引入这个JS:

  • Server项目:_Host.cshtml里加 <script src="file-helpers.js"></script>
  • WebAssembly项目:index.html里加同样的代码

你之前的问题出在哪?

  1. JS代码执行时机不对:Blazor组件还没渲染好,你的JS就去getElementById,自然找不到元素
  2. 直接操作DOM和Blazor冲突:Blazor会管理DOM渲染,你用JS改的内容可能被组件重新渲染覆盖
  3. @onchange调用JS的方式不符合Blazor的交互逻辑,应该用C#事件或者规范的JS互操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 09:20:00