在Blazor的C#代码中如何中途取消BlockBlobClient的上传流程
Blazor WebAssembly Azure Blob 上传取消解决方案
1. 先排查删除Blob报错的根因
你遇到的删除失败大概率是两个常见配置问题:
- SAS权限不足:你从
GetAzureUploadURLFile接口获取的SAS令牌默认只配置了写入/上传权限,没有删除权限,调用DeleteIfExistsAsync会直接返回403权限错误。更安全的方案是不要在前端做删除操作,取消时把状态传给后端,由后端用更高权限的服务端客户端删除Blob和对应数据库记录,避免前端暴露带删除权限的SAS。 - CORS配置缺失:Blazor WebAssembly运行在浏览器端,Azure存储账户的CORS规则需要允许你的前端站点Origin发起
DELETE请求,否则跨域规则会直接拦截删除请求。
2. 正确使用Azure SDK内置的中止机制
你提到的abort中止机制,就是Azure SDK对原生CancellationToken的内置支持,比你自定义轮询InfoBool的方案响应更快,不需要等一个完整块上传完成才检测取消状态,可以直接中止正在进行的HTTP请求:
- 调整方法参数,新增
CancellationToken入参,前端绑定取消按钮触发CancellationTokenSource.Cancel()即可传递取消信号 - 所有异步操作都传入取消令牌即可实现自动中止:
public async Task<InfoBool> HandleFilesUpload(FileChangedEventArgs e, IProgress<Tuple<int, int, string>> progressHandler, IProgress<Tuple<int,string>> fileCountHandler, ExternalFileDTO fileTemplate, CancellationToken cancellationToken) // 替换自定义的isCancelling参数 { // ... 原有逻辑 while ((bytesRead = await bufferedStream.ReadAsync(buffer, 0, BufferSize, cancellationToken)) > 0) { // ... 原有逻辑 // 上传块时传入取消令牌,触发取消时会直接中止当前上传请求 await blockBlobclient.StageBlockAsync(base64BlockId, new MemoryStream(buffer, 0, bytesRead), cancellationToken: cancellationToken); // ... 原有逻辑 } }
触发取消时会抛出OperationCanceledException,你在catch块捕获该异常走清理逻辑即可。
3. 取消后的标准清理流程
不需要强行删除未提交分块的Blob:只要你没有调用CommitBlockListAsync,已经上传的分块只会作为未提交块存在,Azure存储会在7天后自动清理这些未提交块,不会占用计费空间。如果需要即时清理:
- 优先走后端接口:把取消状态传给
_azureservice.VerifyFileAsync,后端用服务端Blob客户端删除对应资源,同时标记数据库记录为已取消即可。 - 必须前端清理的话,先确保SAS有删除权限、CORS配置了DELETE方法,再调用
DeleteIfExistsAsync,不需要先提交块列表。
4. 现有代码优化点
你已经用using包裹了bufferedStream,不需要再手动调用Dispose方法,多余的调用可以直接删除。
内容的提问来源于stack exchange,提问作者Brett JB
相关产品推荐
相关产品推荐

