更新ETag匹配的Azure Table Storage实体时出现400错误求助
问题:Azure Table Storage更新实体时手动添加If-Match头失败,移除后正常的原因
问题场景
你尝试从Azure Table Storage中获取实体,递增其num属性后执行更新操作。核心代码如下:
var t = cc.GetTableReference("tableName"); var query = new TableQuery(); query.Where("PartitionKey eq 'myPartitionKey'"); var res = t.ExecuteQuery(query); var ent = res.FirstOrDefault(); var num = ent.Properties["num"].Int64Value.Value; ent.Properties["num"].Int64Value = num + 1; var updateOperation = TableOperation.Replace(ent); // 带OperationContext时执行失败 t.Execute(updateOperation, null,new OperationContext { UserHeaders = new Dictionary<string, string> { { "If-Match", ent.ETag } } }); // 移除OperationContext后执行成功 // t.Execute(updateOperation);
你疑惑为什么手动添加If-Match头会导致更新失败,去掉后就正常。
原因分析
问题出在重复设置了If-Match请求头:
- Azure Table Storage SDK的
TableOperation.Replace方法本身就内置了乐观并发控制逻辑——它会自动读取你获取到的实体ent的ETag值,并在请求中添加If-Match: {ent.ETag}头,确保只有当服务端上的实体ETag和你本地的一致时,更新才会生效(避免并发更新冲突)。 - 当你手动在
OperationContext.UserHeaders中再次添加If-Match头时,会导致请求中出现两个相同的If-Match头(或者你的手动设置覆盖了SDK的默认值,但逻辑上值是一致的),而Azure Table Storage服务端会拒绝这种存在重复关键请求头的请求,从而导致更新失败。
解决方案
完全不需要手动设置If-Match头,直接使用SDK的默认逻辑即可:
var updateOperation = TableOperation.Replace(ent); // 直接执行,SDK自动处理If-Match头 t.Execute(updateOperation);
如果你的业务需要自定义其他请求头,确保不要重复设置SDK已经自动处理的头(比如If-Match、If-None-Match这类并发控制相关的头),避免触发服务端的请求合法性校验错误。
内容的提问来源于stack exchange,提问作者Nick Chan Abdullah
相关产品推荐
相关产品推荐

