Azure DevOps Server REST API PUT请求未提供API版本报错排查
嘿,我来帮你排查这个问题——从你给出的错误信息和最终请求URL来看,问题其实很明确,咱们一步步来拆解解决:
问题根源
首先看你最终生成的请求URL:
http://138.202.18.216:8070/Samples/19e02b27-74ab-40dd-a519-ece38fafa870/_apis/build/Definitions/11?revision=5?api-version=5.0
这里有个致命的格式错误:URL里出现了两个?符号。HTTP规范里,第一个?用来开启查询参数列表,后续的参数必须用&来分隔,而不是重复用?。Azure DevOps的API解析时,会把第二个?当成路径的一部分,导致api-version=5.0完全没被识别成有效的版本参数,这就是为什么会抛出VssVersionNotSpecifiedException错误。
另外,还有个逻辑误区:你想要修改的是项目描述,但当前代码是通过构建定义的API来操作的——你在更新构建定义对象里的project.description字段,这根本不是修改项目描述的正确方式,就算URL修好了,这个操作也不会生效。
解决方法
1. 先修复URL格式问题(如果还要继续用构建定义API)
如果只是想先解决当前PUT请求的报错,你需要修正URL的参数拼接方式。因为$relDef.url已经自带了?revision=5这样的参数,直接在后面加?api-version=5.0就会导致重复问号。可以用两种方式处理:
# 方式一:去掉原URL的参数,重新拼接api-version $cleanDefUrl = $relDef.url.Split('?')[0] $updateUrl = "$cleanDefUrl?api-version=5.0" # 方式二:保留原参数,用&连接新参数 $updateUrl = "$($relDef.url)&api-version=5.0"
然后用这个$updateUrl来发起PUT请求即可。
2. 正确修改项目描述的代码(你的实际需求)
如果你的目标是修改项目描述,应该调用项目管理的REST API,而不是构建定义API。给你写个示例代码:
$projects.value | ForEach-Object { $currentProject = $_ # 项目管理API对应的AreaId $projectAreaId = "6d3353ef-2c4d-4215-824b-87e503b8d27d" $tfsBaseUrl = GetUrl -orgUrl $orgUrl -header $header -AreaId $projectAreaId # 获取项目详情 $projectDetailUrl = "$tfsBaseUrl/_apis/projects/$($currentProject.id)?api-version=5.0" $projectDetail = Invoke-RestMethod $projectDetailUrl -Method Get -Headers $header -ContentType "application/json" # 修改描述 $projectDetail.description = "Hallo!!!" $body = $projectDetail | ConvertTo-Json -Depth 100 -Compress $bodyBytes = [System.Text.Encoding]::UTF8.GetBytes($body) # 发起更新请求 $updatedProject = Invoke-RestMethod $projectDetailUrl -Method Put -Headers $header -ContentType "application/json" -Body $bodyBytes Write-Host "项目 $($currentProject.name) 的描述已更新为: $($updatedProject.description)" -ForegroundColor Green }
额外注意事项
- 确保你的账号拥有Project Administrators角色权限,否则会返回权限不足的错误。
- Azure DevOps Server 2019对应的API版本确实是5.0,这个不用改。
- 用
ConvertTo-Json时一定要加-Depth 100,不然嵌套的项目对象会被截断,导致请求失败。
内容的提问来源于stack exchange,提问作者Mar Tin
相关产品推荐
相关产品推荐

