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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 16:12:49