Blazor InputFile 组件上传文件教程

Blazor的InputFile组件是官方推荐的文件上传方式,封装HTML input type="file"并提供C# API读取文件流,但不自动发送HTTP请求,需手动实现上传逻辑。

Blazor 的 InputFile 组件是 WebAssembly 和 Server 两种托管模型下上传文件的官方推荐方式,它封装了原生 HTML ,并提供便捷的 C# API 来读取文件内容。关键点在于:它不直接发送 HTTP 请求,而是让你自行处理文件流(如读取、校验、分块或调用后端 API),所以“上传”动作需要你额外实现。

基础用法:绑定文件并读取字节数组

最简单的场景是用户选中一个文件后,立即读取其全部内容到内存:

  • 在 Razor 页面中添加
  • @code 块中定义 OnFileSelected 方法,接收 InputFileChangeEventArgs
  • 调用 file.Data.ReadBytesAsync(file.Size) 获取 byte[](注意:仅适用于小文件,如头像、配置文件)

示例片段:


@code {
  private async Task OnFileSelected(InputFileChangeEventArgs e) {
    var file = e.File;
    if (file.Size       var bytes = await file.Data.ReadBytesAsync(file.Size);
      // 后续处理 bytes,比如保存到本地或上传到服务器
    }
  }
}

多文件上传与进度显示(WebAssembly 专用)

WebAssembly 模型支持通过 InputFile 一次性选择多个文件(设置 multiple 属性),但 Server 模型受限于 SignalR 传输机制,不建议直接传大文件。若需进度反馈:

  • 使用 Stream + StreamReader 分块读取(避免内存爆炸)
  • 配合 Progress 报告已读字节数,再换算成百分比
  • 注意:WebAssembly 中 JS 运行时对大文件流式读取支持良好,Server 模式需改用传统表单或 multipart/form-data 提交

上传到后端 API(推荐 HttpClient 方式)

InputFile 本身不发请求,你需要手动构造 MultipartFormDataContent 并用 HttpClient 发送:

  • 创建 var content = new MultipartFormDataContent()
  • content.Add(new StreamContent(file.Data.OpenReadStream()), "file", file.Name) 添加文件流
  • 可附加其他字段,如 content.Add(new StringContent("doc", Encoding.UTF8), "category")
  • 调用 http.PostAsync("/api/upload", content),服务端用 IFormFile 接收

⚠️ 注意:Server 模式下 file.Data.OpenReadStream() 返回的是客户端上传的临时流,必须在当前请求生命周期内完成读取;WebAssembly 则完全在浏览器内存中操作。

常见问题与规避技巧

  • 文件为空或 Size=0:检查是否误用了 e.GetMultipleFiles().FirstOrDefault() 却没判空;或未等待异步读取完成就访问结果
  • 大文件卡死或 OOM:禁用 ReadBytesAsync,改用 OpenReadStream() + 流式上传或分片上传
  • Server 模式上传失败:确认 Startup.csProgram.cs 中设置了足够大的 MaxRequestBodySize(如 options.Limits.MaxRequestBodySize = 100_000_000;
  • 中文文件名乱码:后端接收时用 file.FileName(非 ContentDisposition 解析),前端无需特殊编码

基本上就这些。掌握 InputFile 的核心是理解它只负责“读”,不负责“传”——剩下的交给你的逻辑和网络层。