在 Powershell 中更新 VSTS WorkItem 的正确 Invoke-RestMethod 语法是什么 - 构建包含 Windows 路径的 JSON 字符串
What is the correct Invoke-RestMethod syntax to update a VSTS WorkItem in Powershell - constructing a JSON string containing Windows paths
尝试使用 Invoke-RestMethod 更新现有 VSTS 工作项时,我不断收到
You must pass a valid patch document in the body of the request.
这是我要传递的内容
$Body = '[{ "op": "test", "path": "/rev", "value": 1},{ "op": "add", "path": "/fields/System.IterationPath", "value":"' + $caseIterationPath + '"},{ "op": "add", "path": "/fields/System.AreaPath", "value":"' + $caseAreaPath + '"}]'
Invoke-RestMethod -Uri "$rootUri/_apis/wit/workitems/$($case.id)?$apiVersion" -Method PATCH -ContentType application/json-patch+json -Headers @{Authorization= $authorization} -Body $Body
正文展开为
"[{ "op": "test", "path": "/rev", "value": 1},{ "op": "add", "path": "/fields/System.IterationPath", "value":"Foo\Bar 2016.416.4.02"},{ "op": "add", "path": "/fields/System.AreaPath", "value":"Foo\Apps\Bar Stool\Eating"}]"
如有任何帮助,我们将不胜感激!
我认为您可能需要转义 AreaPath 值中的反斜杠。从 documentation 的示例中,他们使用双反斜杠。
{
"id": 299,
"rev": 2,
"fields": {
"System.AreaPath": "Fabrikam-Fiber-Git\Website",
"System.TeamProject": "Fabrikam-Fiber-Git",
"System.IterationPath": "Fabrikam-Fiber-Git",
"System.WorkItemType": "Task",
"System.State": "To Do",
"System.Reason": "New task",
"System.CreatedDate": "2014-12-29T20:49:21.617Z",
"System.CreatedBy": "Jamal Hartnett <fabrikamfiber4@hotmail.com>",
"System.ChangedDate": "2014-12-29T20:49:23.933Z",
"System.ChangedBy": "Jamal Hartnett <fabrikamfiber4@hotmail.com>",
"System.Title": "JavaScript implementation for Microsoft Account",
"Microsoft.VSTS.Scheduling.RemainingWork": 4,
"System.Description": "Follow the code samples from MSDN",
"System.History": "Moving to the right area path"
},
"relations": [
{
"rel": "System.LinkTypes.Hierarchy-Reverse",
"url": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/wit/workItems/297",
"attributes": {
"isLocked": false,
"comment": "decomposition of work"
}
}
],
"_links": {
"self": {
"href": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/wit/workItems/299"
},
"workItemUpdates": {
"href": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/wit/workItems/299/updates"
},
"workItemRevisions": {
"href": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/wit/workItems/299/revisions"
},
"workItemHistory": {
"href": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/wit/workItems/299/history"
},
"html": {
"href": "https://fabrikam-fiber-inc.visualstudio.com/web/wi.aspx?pcguid=d81542e4-cdfa-4333-b082-1ae2d6c3ad16&id=299"
},
"workItemType": {
"href": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c/_apis/wit/workItemTypes/Task"
},
"fields": {
"href": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/wit/fields"
}
},
"url": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/wit/workItems/299"
}
JSON 使用 \
作为 转义字符 ;例如,\t
是 TAB 字符的转义序列(Unicode 代码点 0x9
)。
因此,为了使用文字 \
- 例如在 Windows 路径中 - 你必须将其转义为 \
.
你 可以 手动转义你用来合成 JSON 字符串的所有变量值 $caseIterationPath -replace '\', '\'
(原文如此)。
但是,首先构建常规 PowerShell 数据结构可能更容易,然后让ConvertTo-Json
进行所需的转义关于转换。
手头的案例:
# Sample values.
$caseIterationPath = 'c:\path\to\iteration'
$caseAreaPath = 'c:\path\to\area'
# Construct an array of hashtables to be converted to JSON later.
$Body = @(
@{
op = 'test'
path = '/rev'
value = 1
}
@{
op = 'add'
path = '/fields/System.IterationPath'
value = $caseIterationPath
}
@{
op = 'add'
path = '/fields/System.AreaPath'
value = $caseAreaPath
}
)
# Convert the array to a string containing JSON.
# ConvertTo-Json will perform any required escaping.
$jsonBody = ConvertTo-Json $Body
# Invoke the REST method.
Invoke-RestMethod -Uri "$rootUri/_apis/wit/workitems/$($case.id)?$apiVersion" `
-Method PATCH -ContentType application/json-patch+json `
-Headers @{Authorization= $authorization} `
-Body $jsonBody
在上面的代码中,$jsonBody
最终包含以下内容 - 请注意 \
实例如何正确转义为 \
:
[
{
"path": "/rev",
"op": "test",
"value": 1
},
{
"path": "/fields/System.IterationPath",
"op": "add",
"value": "c:\path\to\iteration"
},
{
"path": "/fields/System.AreaPath",
"op": "add",
"value": "c:\path\to\area"
}
]
尝试使用 Invoke-RestMethod 更新现有 VSTS 工作项时,我不断收到
You must pass a valid patch document in the body of the request.
这是我要传递的内容
$Body = '[{ "op": "test", "path": "/rev", "value": 1},{ "op": "add", "path": "/fields/System.IterationPath", "value":"' + $caseIterationPath + '"},{ "op": "add", "path": "/fields/System.AreaPath", "value":"' + $caseAreaPath + '"}]'
Invoke-RestMethod -Uri "$rootUri/_apis/wit/workitems/$($case.id)?$apiVersion" -Method PATCH -ContentType application/json-patch+json -Headers @{Authorization= $authorization} -Body $Body
正文展开为
"[{ "op": "test", "path": "/rev", "value": 1},{ "op": "add", "path": "/fields/System.IterationPath", "value":"Foo\Bar 2016.416.4.02"},{ "op": "add", "path": "/fields/System.AreaPath", "value":"Foo\Apps\Bar Stool\Eating"}]"
如有任何帮助,我们将不胜感激!
我认为您可能需要转义 AreaPath 值中的反斜杠。从 documentation 的示例中,他们使用双反斜杠。
{
"id": 299,
"rev": 2,
"fields": {
"System.AreaPath": "Fabrikam-Fiber-Git\Website",
"System.TeamProject": "Fabrikam-Fiber-Git",
"System.IterationPath": "Fabrikam-Fiber-Git",
"System.WorkItemType": "Task",
"System.State": "To Do",
"System.Reason": "New task",
"System.CreatedDate": "2014-12-29T20:49:21.617Z",
"System.CreatedBy": "Jamal Hartnett <fabrikamfiber4@hotmail.com>",
"System.ChangedDate": "2014-12-29T20:49:23.933Z",
"System.ChangedBy": "Jamal Hartnett <fabrikamfiber4@hotmail.com>",
"System.Title": "JavaScript implementation for Microsoft Account",
"Microsoft.VSTS.Scheduling.RemainingWork": 4,
"System.Description": "Follow the code samples from MSDN",
"System.History": "Moving to the right area path"
},
"relations": [
{
"rel": "System.LinkTypes.Hierarchy-Reverse",
"url": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/wit/workItems/297",
"attributes": {
"isLocked": false,
"comment": "decomposition of work"
}
}
],
"_links": {
"self": {
"href": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/wit/workItems/299"
},
"workItemUpdates": {
"href": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/wit/workItems/299/updates"
},
"workItemRevisions": {
"href": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/wit/workItems/299/revisions"
},
"workItemHistory": {
"href": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/wit/workItems/299/history"
},
"html": {
"href": "https://fabrikam-fiber-inc.visualstudio.com/web/wi.aspx?pcguid=d81542e4-cdfa-4333-b082-1ae2d6c3ad16&id=299"
},
"workItemType": {
"href": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c/_apis/wit/workItemTypes/Task"
},
"fields": {
"href": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/wit/fields"
}
},
"url": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/wit/workItems/299"
}
JSON 使用 \
作为 转义字符 ;例如,\t
是 TAB 字符的转义序列(Unicode 代码点 0x9
)。
因此,为了使用文字 \
- 例如在 Windows 路径中 - 你必须将其转义为 \
.
你 可以 手动转义你用来合成 JSON 字符串的所有变量值 $caseIterationPath -replace '\', '\'
(原文如此)。
但是,首先构建常规 PowerShell 数据结构可能更容易,然后让ConvertTo-Json
进行所需的转义关于转换。
手头的案例:
# Sample values.
$caseIterationPath = 'c:\path\to\iteration'
$caseAreaPath = 'c:\path\to\area'
# Construct an array of hashtables to be converted to JSON later.
$Body = @(
@{
op = 'test'
path = '/rev'
value = 1
}
@{
op = 'add'
path = '/fields/System.IterationPath'
value = $caseIterationPath
}
@{
op = 'add'
path = '/fields/System.AreaPath'
value = $caseAreaPath
}
)
# Convert the array to a string containing JSON.
# ConvertTo-Json will perform any required escaping.
$jsonBody = ConvertTo-Json $Body
# Invoke the REST method.
Invoke-RestMethod -Uri "$rootUri/_apis/wit/workitems/$($case.id)?$apiVersion" `
-Method PATCH -ContentType application/json-patch+json `
-Headers @{Authorization= $authorization} `
-Body $jsonBody
在上面的代码中,$jsonBody
最终包含以下内容 - 请注意 \
实例如何正确转义为 \
:
[
{
"path": "/rev",
"op": "test",
"value": 1
},
{
"path": "/fields/System.IterationPath",
"op": "add",
"value": "c:\path\to\iteration"
},
{
"path": "/fields/System.AreaPath",
"op": "add",
"value": "c:\path\to\area"
}
]