Azure Pipeline调用DevOps API更新Wiki页面失败求助
问题分析与修复方案
核心问题排查
路径编码错误导致更新目标不匹配
你在更新请求中使用了硬编码的URL编码路径$pg="%2FBranch%+auditor%2FDevelop",这种编码方式和Azure DevOps API期望的格式不一致(尤其是空格的%+编码与标准%20编码差异),导致API未找到目标页面,反而静默创建了新页面(PUT请求在路径不存在时会执行创建),但你误以为是更新原页面。注释导致变量未初始化(潜在问题)
代码中$pageDetails = $response.Content | ConvertFrom-Json被注释,导致$currentVersion = $pageDetails.version完全无效,虽未直接影响更新操作,但会干扰调试信息准确性,后续扩展代码时可能引发问题。ETag未处理引号
Azure DevOps返回的ETag通常带有双引号(例如"xxxxxx"),直接传入If-Match头会导致ETag匹配失败,触发PUT请求的创建逻辑而非更新逻辑。未验证实际操作结果
仅通过Invoke-RestMethod无异常判断成功,但实际可能执行的是创建操作而非更新,需要验证响应中的页面ID是否为目标ID(769)。
修复后的代码
$fullUrl = "https://dev.azure.com/$(organization)/$(project)/_apis/wiki/wikis/$(wikiIdentifier)/pages/769?includeContent=True&api-version=7.1" Write-Host "Full URL: $fullUrl" try { Write-Host "`n--- Step 1: Fetch Page Metadata and Current Version ---" Write-Host "GET URL: $fullUrl" $encodedToken = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$(token)")) $response = Invoke-WebRequest -Uri $fullUrl ` -Headers @{ Authorization = $encodedToken Accept = "application/json" } ` -Method Get $etag = $response.Headers["ETag"] Write-Host "Status Code: $($response.StatusCode)" # 处理ETag的数组格式和引号 if ($etag -is [System.Array]) { $etag = $etag[0] } $etag = $etag.Trim('"') # 移除ETag的双引号 Write-Host "eTag: $etag" # 解析页面详情,验证目标路径 $pageDetails = $response.Content | ConvertFrom-Json $currentVersion = $pageDetails.version Write-Host "currentVersion: $currentVersion" Write-Host "Target Page Path: $($pageDetails.path)" # 新内容 $newContent = @" ## This text was written during a pipeline run. "@ Write-Host "`n--- Step 2: Prepare Request Body ---" # 构建请求体 $requestBody = @{ content = $newContent } | ConvertTo-Json -Depth 10 -Compress Write-Host "Request body: $requestBody" # --- 执行更新操作 --- Write-Host "`n--- Step 3: Update the Page ---" try { # 使用GET请求返回的原始路径,进行标准URL编码 $pg = $pageDetails.path $encodedPath = [Uri]::EscapeDataString($pg) $updateUrl = "https://dev.azure.com/$(organization)/$(project)/_apis/wiki/wikis/$(wikiIdentifier)/pages?path=$encodedPath&api-version=7.1" Write-Host "Update URL: $updateUrl" Write-Host "Updating wiki page..." # 使用Invoke-WebRequest获取明确响应信息 $updateResponse = Invoke-WebRequest -Uri $updateUrl ` -Headers @{ Authorization = $encodedToken Accept = "application/json" "Content-Type" = "application/json" "If-Match" = $etag } ` -Method Put -Body $requestBody Write-Host "Page update status code: $($updateResponse.StatusCode)" $updateResult = $updateResponse.Content | ConvertFrom-Json Write-Host "Updated Page ID: $($updateResult.id)" # 验证是否更新了目标页面 if ($updateResult.id -eq 769) { Write-Host "Successfully updated target page (ID: 769)" } else { Write-Host "Warning: Updated page ID ($($updateResult.id)) does not match target ID (769) - check if new page was created" } } catch { Write-Host "Failed to update page: $($_.Exception.Message)" if ($_.Exception.Response) { $responseStream = $_.Exception.Response.GetResponseStream() $reader = New-Object System.IO.StreamReader($responseStream) $responseBody = $reader.ReadToEnd() Write-Host "Response body: $responseBody" } throw } }
关键调整说明
- 路径验证与编码:直接使用GET请求返回的
$pageDetails.path作为目标路径,并用[Uri]::EscapeDataString进行标准URL编码,确保路径完全匹配目标页面。 - ETag处理:添加
$etag = $etag.Trim('"')移除ETag的双引号,保证If-Match头格式符合API要求。 - 响应验证:改用
Invoke-WebRequest获取明确的响应状态码和结果,验证更新的页面ID是否为目标ID(769),避免误判操作类型。 - 修复变量初始化:取消注释页面详情解析代码,确保调试信息完整,同时验证获取的页面路径与硬编码路径是否一致。
内容的提问来源于stack exchange,提问作者cdrrr
相关产品推荐
相关产品推荐

