使用BlobContainerClient操作Azure Blob Storage遇412条件不满足错误
Azure Blob Storage 下载删除Blob时部署后出现412错误
本地使用BlobContainerClient从Azure Blob Storage下载Blob到本地后删除的流程运行正常,但部署后报以下错误:
412 (The condition specified using HTTP conditional header(s) is not met.)
示例代码:
BlobContainerClient container = new BlobContainerClient(azureBlobSettings.Connectionstring, azureBlobSettings.Containername); var blobList = container.GetBlobs(); foreach (var blobItem in blobList) { if (blobItem.Name.Contains(".csv")) { LogInfo($"Downloading file {blobItem.Name} ..."); var blob = container.GetBlobClient(blobItem.Name); var blobSplit = blob.Name.Split("/"); var blobPath = blobSplit[0]; var blobName = blobSplit[1]; blob.DownloadTo($"{csvSettings.TargetPath}{blobName}"); blob.DeleteIfExists(); } }
详细错误栈:
at Azure.Storage.Blobs.BlobRestClient.Download(String snapshot, String versionId, Nullable`1 timeout, String range, String leaseId, Nullable`1 rangeGetContentMD5, Nullable`1 rangeGetContentCRC64, String encryptionKey, String encryptionKeySha256, Nullable`1 encryptionAlgorithm, Nullable`1 ifModifiedSince, Nullable`1 ifUnmodifiedSince, String ifMatch, String ifNoneMatch, String ifTags,CancellationToken cancellationToken) at Azure.Storage.Blobs.Specialized.BlobBaseClient.StartDownloadAsync(HttpRange range, BlobRequestConditions conditions, Boolean rangeGetContentHash, Int64 startOffset, Boolean async, CancellationToken cancellationToken) at Azure.Storage.Blobs.Specialized.BlobBaseClient.DownloadStreamingInternal(HttpRange range, BlobRequestConditions conditions, Boolean rangeGetContentHash, IProgress`1 progressHandler, String operationName, Boolean async, CancellationToken cancellationToken) at Azure.Storage.Blobs.Specialized.BlobBaseClient.DownloadStreaming(HttpRange range, BlobRequestConditions conditions, Boolean rangeGetContentHash, IProgress`1 progressHandler, CancellationToken cancellationToken) at Azure.Storage.Blobs.PartitionedDownloader.DownloadTo(Stream destination, BlobRequestConditions conditions, CancellationToken cancellationToken) at Azure.Storage.Blobs.Specialized.BlobBaseClient.StagedDownloadAsync(Stream destination, BlobRequestConditions conditions, IProgress`1 progressHandler, StorageTransferOptions transferOptions, Boolean async, CancellationToken cancellationToken) at Azure.Core.Pipeline.TaskExtensions.EnsureCompleted[T](Task`1 task) at Azure.Storage.Blobs.Specialized.BlobBaseClient.DownloadTo(String path, BlobRequestConditions conditions, StorageTransferOptions transferOptions, CancellationToken cancellationToken) at Azure.Storage.Blobs.Specialized.BlobBaseClient.DownloadTo(String path, CancellationToken cancellationToken) at Azure.Storage.Blobs.Specialized.BlobBaseClient.DownloadTo(String path)
问题原因及解决办法
1. 并发操作冲突
部署后多实例同时执行逻辑,或Blob在获取列表后到下载前被修改/删除。GetBlobs()返回的是快照数据,遍历到Blob时它可能已被其他操作修改,导致下载时条件不满足。
解决:
遍历Blob时记录ETag,下载时指定匹配条件,确保下载的是列表获取时的版本:
var blob = container.GetBlobClient(blobItem.Name); // 仅当Blob的ETag与列表中获取的一致时才下载 var conditions = new BlobRequestConditions { IfMatch = blobItem.Properties.ETag }; blob.DownloadTo($"{csvSettings.TargetPath}{blobName}", conditions);
2. Blob被其他进程锁定或修改
部署环境中可能有其他服务同时访问Blob,比如上传未完成、Blob被租赁锁定。
解决:
- 检查Blob是否有活跃租赁,有则先释放再操作;
- 改用Azure Event Grid监听Blob创建事件触发下载,替代定时轮询,确保Blob上传完成后再处理。
3. 分区下载的条件冲突
DownloadTo内部分块下载,若Blob在分块过程中被修改,后续分块请求会触发412错误。
解决:
改用DownloadContent先将Blob内容读到内存再写入本地,减少分块冲突:
var content = blob.DownloadContent(); File.WriteAllBytes($"{csvSettings.TargetPath}{blobName}", content.Value.Content);
4. 目录结构处理异常
代码中手动用Split("/")处理Blob名称,若Blob名称含多个斜杠或为根目录下文件,会导致数组越界,间接引发异常(错误码可能表现为412)。
解决:
用Path.GetFileName安全获取文件名:
var blobName = Path.GetFileName(blob.Name);
内容的提问来源于stack exchange,提问作者Anthony Cuartero
相关产品推荐
相关产品推荐

