Blazor Server+MudBlazor上传大PDF至SQL Server失败问题求助
解决方案:Blazor Server + EF 数据库优先实现大PDF存储与显示
1. 修复大文件上传的读取逻辑
直接转byte[]容易出现大文件读取不完整的问题,改用流式读取确保文件完整加载:
前端InputFile组件(结合MudBlazor)
<InputFile OnChange="HandleFileSelected" accept=".pdf" /> <MudButton OnClick="SavePdf" Disabled="@(selectedFile == null)">保存PDF</MudButton> @code { private IBrowserFile selectedFile; private void HandleFileSelected(InputFileChangeEventArgs e) { selectedFile = e.File; // 可选:限制最大文件大小,比如100MB if (selectedFile.Size > 1024 * 1024 * 100) { // 这里可以加MudAlert提示文件过大 return; } } }
后端流式读取文件(避免内存溢出)
private async Task<byte[]> ReadFileToByteArray(IBrowserFile file) { using var memoryStream = new MemoryStream(); // 显式设置最大允许大小,覆盖EF默认的512KB限制 await file.OpenReadStream(maxAllowedSize: 1024 * 1024 * 100).CopyToAsync(memoryStream); return memoryStream.ToArray(); } private async Task SavePdf() { if (selectedFile == null) return; var pdfData = await ReadFileToByteArray(selectedFile); var pdfModel = new Pdfs { FileName = selectedFile.Name, ContentType = selectedFile.ContentType, PdfData = pdfData, UploadTime = DateTime.Now }; _context.Pdfs.Add(pdfModel); await _context.SaveChangesAsync(); }
2. 配置EF与SQL Server支持大字段
修正EF模型配置
数据库优先生成的模型可能默认限制字段长度,手动在DbContext中取消限制:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Pdfs>() .Property(p => p.PdfData) .HasMaxLength(null) // 对应SQL Server的varbinary(MAX) .IsRequired(false); }
调整SQL Server数据包大小(超大文件可选)
如果上传文件超过4MB,修改SQL Server的最大允许数据包:
sp_configure 'show advanced options', 1; RECONFIGURE; sp_configure 'max allowed packet', 104857600; -- 设置为100MB RECONFIGURE;
3. 修复大PDF的显示问题
大文件用Data URL加载会有浏览器长度限制,改用后端返回FileResult的方式:
后端添加PDF读取接口
[Route("api/pdf")] [ApiController] public class PdfController : ControllerBase { private readonly YourDbContext _context; public PdfController(YourDbContext context) { _context = context; } [HttpGet("{id}")] public async Task<IActionResult> GetPdf(int id) { var pdf = await _context.Pdfs.FindAsync(id); if (pdf == null) return NotFound(); return File(pdf.PdfData, pdf.ContentType, pdf.FileName); } }
前端用embed标签加载
@if (currentPdf != null) { <embed src="@($"api/pdf/{currentPdf.Id}")" type="application/pdf" width="100%" height="600px" /> }
4. 可选:添加上传进度条(MudBlazor版)
利用流式读取的进度回调实现进度提示:
private async Task<byte[]> ReadFileWithProgress(IBrowserFile file, IProgress<int> progress) { using var memoryStream = new MemoryStream(); var stream = file.OpenReadStream(1024 * 1024 * 100); var buffer = new byte[8192]; int bytesRead; long totalRead = 0; while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0) { await memoryStream.WriteAsync(buffer, 0, bytesRead); totalRead += bytesRead; progress.Report((int)((totalRead * 100) / file.Size)); } return memoryStream.ToArray(); }
前端使用:
<MudLinearProgress Value="@uploadProgress" Visible="@(uploadProgress > 0 && uploadProgress < 100)" /> @code { private int uploadProgress; private async Task SavePdf() { if (selectedFile == null) return; var progress = new Progress<int>(value => uploadProgress = value); var pdfData = await ReadFileWithProgress(selectedFile, progress); // 保存逻辑... uploadProgress = 100; } }
内容的提问来源于stack exchange,提问作者Cody
相关产品推荐
相关产品推荐

