在 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"
    }
]