SQL Server大文件上传报错排查及解决方案咨询
解决方案建议
1. 修复前端读取文件的大小限制
错误的直接原因是Upload方法中调用file.OpenReadStream()时未传入最大允许大小参数,IBrowserFile.OpenReadStream()的默认限制为512000字节(500KB),和你预先定义的MaxSizeFiles不匹配。
修改Upload方法中的流读取代码:
// 替换原代码中的 using Stream s = file.OpenReadStream(); using Stream s = file.OpenReadStream(MaxSizeFiles);
这样就能使用你设置的long.MaxValue作为最大文件大小限制,解除500KB的限制。
2. 检查后端API的请求大小限制
即使前端解除限制,ASP.NET Core后端默认存在请求大小限制(默认约30MB),需要确保后端允许大文件上传:
- 在
Program.cs全局配置请求大小:
builder.Services.Configure<Microsoft.AspNetCore.Http.Features.FormOptions>(options => { options.MultipartBodyLengthLimit = long.MaxValue; // 设置表单请求的最大大小 options.ValueLengthLimit = int.MaxValue; // 设置单个表单值的最大长度 });
- 若使用控制器,可在对应API方法上添加特性强化限制:
[RequestSizeLimit(long.MaxValue)] [RequestFormLimits(MultipartBodyLengthLimit = long.MaxValue)] public async Task<IActionResult> AddArchivoToTarea(AddArchivoTareaRequestDTO request) { // 业务逻辑代码 }
3. 确保SQL Server字段支持大文件存储
存储大文件不能使用普通的VARBINARY(n)类型,需使用以下类型:
VARBINARY(MAX):支持最大2GB文件,满足多数场景需求FILESTREAM:适合超过2GB的文件或需要高效流式访问的场景
检查数据表中存储文件内容的字段类型,确认是VARBINARY(MAX)或对应FILESTREAM类型。
4. 优化内存占用(可选但推荐)
当前代码将整个文件读入byte[]再传递给API,大文件会占用大量内存,可能引发内存溢出。建议改为流式上传:
前端修改
无需将文件转为byte[],直接通过流传递:
private async void Upload() { List<string>? notUploadFiles = new(); foreach (var file in Files) { string extn = Path.GetExtension(file.Name); using var content = new MultipartFormDataContent(); content.Add(new StringContent(Tarea.Id.ToString()), "TareaId"); content.Add(new StringContent(file.Name), "FileName"); content.Add(new StringContent(extn), "Extension"); // 直接添加文件流,避免加载到内存 content.Add(new StreamContent(file.OpenReadStream(MaxSizeFiles)), "FileData", file.Name); var response = await Http.PostAsync("api/tareas/addarchivo", content); if (!response.IsSuccessStatusCode) { notUploadFiles.Add(file.Name); } } // 后续提示逻辑保持不变... }
后端修改
对应API方法接收流式数据:
[RequestSizeLimit(long.MaxValue)] [RequestFormLimits(MultipartBodyLengthLimit = long.MaxValue)] public async Task<IActionResult> AddArchivoToTarea() { var form = await Request.ReadFormAsync(); var tareaId = int.Parse(form["TareaId"]); var fileName = form["FileName"]; var extension = form["Extension"]; var file = form.Files["FileData"]; // 直接用文件流写入数据库,不加载到内存 using var stream = file.OpenReadStream(); var success = await _tareaRepository.AddArchivoToTareaAsync(tareaId, fileName, stream, extension); return success ? Ok() : BadRequest(); }
数据库操作时,通过SqlParameter传入流:
public async Task<bool> AddArchivoToTareaAsync(int tareaId, string fileName, Stream fileStream, string extension) { var sql = "INSERT INTO ArchivosTarea (TareaId, Nombre, Contenido, Extension) VALUES (@TareaId, @Nombre, @Contenido, @Extension)"; using var conn = new SqlConnection(_connectionString); await conn.OpenAsync(); var contentParam = new SqlParameter("@Contenido", SqlDbType.VarBinary) { Value = fileStream }; var rowsAffected = await conn.ExecuteAsync(sql, new { TareaId = tareaId, Nombre = fileName, Extension = extension, Contenido = contentParam }); return rowsAffected > 0; }
流式上传避免了大文件占用内存,提升应用稳定性和性能。
内容的提问来源于stack exchange,提问作者jcadafalch
相关产品推荐
相关产品推荐

