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

Blazor Server应用间歇性丢失提交文件附件问题排查求助

问题诊断与修复方案

核心问题:流读取不完整

你的代码里直接用await stream.ReadAsync(buf)读取流,但ReadAsync的返回值是实际读取的字节数,它没法保证一次性读完整个流的所有数据。本地/内网网络稳定,数据传输快,大概率一次就读完了;但外网或平板网络不稳定、延迟高时,就会出现读取不完整(部分丢失)或者完全没读到(全无丢失)的情况。

代码里的具体问题

不管是图片处理还是PDF读取部分,都存在这个漏洞:

var buf = new byte[resizedFile.Size];
using (var stream = resizedFile.OpenReadStream(maxAllowedSize:10000000))
{
    await stream.ReadAsync(buf); // 只读取一次,网络波动时大概率读不全
}

网络波动时,一次ReadAsync读取的字节数会小于buf的长度,剩下的字节都是默认的0,最终存到数据库的就是不完整的附件,甚至是空数据。

修复方案:循环读取流直到完成

替换原有的读取逻辑,确保把流里的所有数据都读到字节数组里。可以先封装一个通用读取方法,再修改业务代码:

通用流读取方法

private async Task<byte[]> ReadStreamToByteArrayAsync(Stream stream)
{
    using var memoryStream = new MemoryStream();
    await stream.CopyToAsync(memoryStream);
    return memoryStream.ToArray();
}

修改后的OnChange方法

List<PkgAttachments> SelectedFiles = new List<PkgAttachments>();        
async Task OnChange(InputFileChangeEventArgs e)
{
    var files = e.GetMultipleFiles();
    foreach(var file in files)
    {
        // 替换扩展名获取方式,避免文件名无"."时报错
        string fileExt = Path.GetExtension(file.Name).TrimStart('.').ToUpper(); 
        if (new[] {"JPG", "JPEG", "BMP", "PNG"}.Contains(fileExt))
        {
            var resizedFile = await file.RequestImageFileAsync(file.ContentType, 830, 715);
            using (var stream = resizedFile.OpenReadStream(maxAllowedSize:10000000))
            {
                byte[] buf = await ReadStreamToByteArrayAsync(stream);
                SelectedFiles.Add(new PkgAttachments { Data = buf, ContentType = file.ContentType, Name = file.Name });
            }
        }
        else if (fileExt == "PDF")
        {
            using (var stream = file.OpenReadStream(maxAllowedSize:10000000))
            {
                byte[] buf = await ReadStreamToByteArrayAsync(stream);
                SelectedFiles.Add(new PkgAttachments { Data = buf, ContentType = file.ContentType, Name = file.Name });
            }
        }
    }
}

额外优化建议

  1. 扩展名获取逻辑:用Path.GetExtension替代原有的Substring方式,避免文件名不含.时抛出异常。
  2. 数据完整性校验:添加到SelectedFiles前,可检查buf.Length是否匹配文件预期大小(比如图片的resizedFile.Size),进一步确保数据完整。

其他排查方向

  • 调整SignalR超时配置:外网环境下Blazor Server的SignalR连接可能因超时中断,导致附件传输中断。在Program.cs中修改配置:
    builder.Services.AddServerSideBlazor()
        .AddHubOptions(options =>
        {
            options.ClientTimeoutInterval = TimeSpan.FromMinutes(5);
            options.KeepAliveInterval = TimeSpan.FromMinutes(2);
        });
    
  • 检查数据库字段限制:确认varbinary(max)字段没有额外的大小限制(虽然理论上支持2GB,但存储过程或实体模型可能有自定义限制)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 07:19:28