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

Blazor组件上传文件夹时如何获取选中根文件夹及子文件夹名称

Blazor获取文件夹上传的根目录及子目录名称方案

Blazor内置的IBrowserFile默认没有暴露浏览器返回的文件相对路径字段,要拿到完整文件夹结构,需要通过JS互操作读取文件的webkitRelativePath属性——浏览器开启webkitdirectory选择模式时,会自动给每个文件填充这个属性,格式为选中的根文件夹/子文件夹1/子文件夹2/文件名,从这个字段就能解析出所有文件夹信息。

1. 添加JS辅助方法

在项目wwwroot目录下新建fileUpload.js,写入以下代码,用于从input DOM元素上读取带路径的文件信息:

window.fileUploadUtil = {
    getFilesWithPath: function (inputEl) {
        return Array.from(inputEl.files).map(file => ({
            name: file.name,
            size: file.size,
            type: file.type,
            relativePath: file.webkitRelativePath,
            lastModified: file.lastModified
        }));
    }
}

在_Host.cshtml(Blazor Server模式)或index.html(Blazor WASM模式)的body末尾引入这个JS文件:

<script src="fileUpload.js"></script>

2. 修改Razor组件代码

给InputFile组件添加元素引用,在选择文件后调用JS获取带路径的文件数据,再解析出根文件夹和所有子文件夹,完整代码如下:

@page "/uploadfolder"
@inject IJSRuntime JS

<InputFile @ref="uploadInput" OnChange="@HandleFolderSelect" webkitdirectory directory />

<div style="margin-top:1rem">
    <p>*选中的根文件夹:*@RootFolderName</p>
    <p>*包含的所有文件夹:*</p>
    <ul>
        @foreach (var folder in AllFolders)
        {
            <li>@folder</li>
        }
    </ul>
</div>

@code {
    private InputFile? uploadInput;
    private string RootFolderName = string.Empty;
    private HashSet<string> AllFolders = new();
    private List<FileDataWithPath> SelectedFiles = new();

    // 自定义接收JS返回文件数据的模型
    private class FileDataWithPath
    {
        public string Name { get; set; } = string.Empty;
        public long Size { get; set; }
        public string Type { get; set; } = string.Empty;
        public string RelativePath { get; set; } = string.Empty;
        public long LastModified { get; set; }
    }

    private async Task HandleFolderSelect(InputFileChangeEventArgs e)
    {
        SelectedFiles.Clear();
        AllFolders.Clear();
        RootFolderName = string.Empty;

        if (uploadInput?.Element is null) return;
        // 调用JS获取带相对路径的文件列表
        SelectedFiles = await JS.InvokeAsync<List<FileDataWithPath>>(
            "fileUploadUtil.getFilesWithPath", 
            uploadInput.Element);

        if (SelectedFiles.Count == 0) return;

        // 解析根文件夹名称:第一个文件路径的第一个斜杠前的内容就是根目录
        var firstPath = SelectedFiles[0].RelativePath;
        var splitIndex = firstPath.IndexOf('/');
        if (splitIndex > 0)
        {
            RootFolderName = firstPath[..splitIndex];
        }

        // 遍历所有文件,提取所有层级的文件夹
        foreach (var file in SelectedFiles)
        {
            // 按正斜杠拆分路径,浏览器返回的路径统一用正斜杠分隔
            var pathSegments = file.RelativePath.Split('/', StringSplitOptions.RemoveEmptyEntries);
            // 最后一段是文件名,只遍历前面的文件夹段
            for (int i = 0; i < pathSegments.Length - 1; i++)
            {
                var currentFolderPath = string.Join('/', pathSegments.Take(i + 1));
                AllFolders.Add(currentFolderPath);
            }
        }
    }
}

补充说明

  • 浏览器出于安全限制,永远不会返回文件在用户本地的绝对路径,你拿到的所有路径都是以选中根文件夹为起点的相对路径。
  • AllFolders会自动去重,默认包含根文件夹,如果只需要子文件夹,过滤掉和RootFolderName值相同的项即可。
  • 如果后续需要读取文件内容上传,直接用InputFileChangeEventArgs的GetMultipleFiles()方法拿到IBrowserFile流即可,可以按文件名和解析到的路径信息做匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 18:39:18