.NET C# Azure开发:如何解决AccessCondition多条件头部不支持异常
错误原因
Azure存储服务的REST API本身不支持同时传入If-Match和If-None-Match两个条件头,你同时为AccessCondition的IfMatchETag和IfNoneMatchETag属性赋值,就会触发Multiple condition headers are not supported异常。
另外你的原始需求存在逻辑矛盾:当overwrite = false时,GenerateIfNotExistsCondition的作用是要求目标Blob不存在才允许操作,而不存在的Blob本身没有Etag,同时要求匹配Etag的逻辑本身不成立。
解决方案
方案1:分支设置条件(推荐,性能最优)
根据overwrite参数的取值分场景设置单一访问条件,完全匹配业务的合理逻辑:
AccessCondition accessCondition; if (overwrite) { // 覆盖场景:仅校验Etag匹配,防止并发修改 accessCondition = AccessCondition.GenerateIfMatchCondition(_etag); } else { // 新建场景:仅校验Blob不存在,禁止覆盖 accessCondition = AccessCondition.GenerateIfNotExistsCondition(); } await _blob.UploadFromByteArrayAsync( metadataContent, 0, metadataContent.Length, accessCondition, null, null, cancellationToken);
方案2:两步校验实现严格双重校验
如果你的业务确实需要在操作前同时校验存在性和Etag,可以先执行一次属性查询做预校验,再执行上传操作,同时捕获并发冲突异常兜底:
try { AccessCondition accessCondition; if (overwrite) { // 预校验:Blob存在且Etag匹配 await _blob.FetchAttributesAsync(cancellationToken); if (_blob.Properties.ETag != _etag) { throw new InvalidOperationException("Etag不匹配,操作被阻止"); } accessCondition = AccessCondition.GenerateIfMatchCondition(_etag); } else { // 预校验:Blob不存在 bool blobExists = await _blob.ExistsAsync(cancellationToken); if (blobExists) { throw new InvalidOperationException("Blob已存在,不允许覆盖"); } accessCondition = AccessCondition.GenerateIfNotExistsCondition(); } // 执行上传 await _blob.UploadFromByteArrayAsync( metadataContent, 0, metadataContent.Length, accessCondition, null, null, cancellationToken); } catch (StorageException ex) when (ex.RequestInformation.HttpStatusCode is 412 or 409) { // 捕获两步操作之间的并发修改冲突 throw new InvalidOperationException("操作执行时发生并发冲突,请重试", ex); }
内容的提问来源于stack exchange,提问作者Nika
相关产品推荐
相关产品推荐

