我正在使用OneLogin REST API,并且似乎无法使用PUT方法进行任何调用。当我在Postman中测试时,我可以传递一个原始的JSON体,如下所示:
{
"role_id_array": [
115028
]
}
到端点:
https://api.us.onelogin.com/api/1/users/ / add_roles
这很好用。但是,当我尝试使用PowerShell的Invoke-RestMethod命令执行相同操作时,我收到400 Bad Request错误。我的代码如下所示:
$Splat = @{
Method = $Method
Uri = https://api.us.onelogin.com/api/1/users/12345678/add_roles
ContentType = "application/json"
Headers = @{authorization = "bearer:$($Token.access_token)"}
Body = @{role_id_array = @(123456)}
}
Invoke-RestMethod @Splat
到目前为止,我对任何GET调用都没有任何问题,只有PUT。另外,如果我运行我通过ConvertTo-Json传入的Body哈希表,输出看起来就像上面的工作示例。有没有人想过为什么这不起作用?
答案 0 :(得分:8)
我能够让PUT
工作!
首先,我使用this blog post here,它有一个很好的方法来检索Invoke-RestMethod
或WebRequest
cmdlet的完整错误消息。
在他的方法中,首先定义一个名为Failure的函数。
function Failure {
$global:helpme = $body
$global:helpmoref = $moref
$global:result = $_.Exception.Response.GetResponseStream()
$global:reader = New-Object System.IO.StreamReader($global:result)
$global:responseBody = $global:reader.ReadToEnd();
Write-Host -BackgroundColor:Black -ForegroundColor:Red "Status: A system exception was caught."
Write-Host -BackgroundColor:Black -ForegroundColor:Red $global:responsebody
Write-Host -BackgroundColor:Black -ForegroundColor:Red "The request body has been saved to `$global:helpme"
break
}
然后,在这样的try Catch块中包装所有的Invoke-RestMethod调用。
try {
$e = Invoke-WebRequest 'https://api.us.onelogin.com/api/1/users/$id' `
-Headers @{ Authorization = "bearer:$token" } `
-Body ( @{ phone = "7709746046" } | ConvertTo-Json ) `
-Method Put -ErrorAction:Stop -ContentType 'application/json'
}
catch {Failure}
现在当您遇到错误时,您可以看到实际的消息,例如
> Status: A system exception was caught.
{"status":{"error":true,"code":400,"type":"bad request","message":{"description":"notes is not a valid attribute for user model","attribute":"notes"}}}
The request body has been saved to $global:helpme
这对帮助我摆脱遇到的错误非常有帮助,并且我能够使用PUT
动词更新用户条目并使其正常工作。
我只需对代码进行两处更改即可使其正常工作。
首先,在URI周围加上引号,因为您的示例代码没有它们,并且您必须在哈希表中围绕字符串使用引号。
最后,将您的角色ID数组传输到ConvertTo-JSON
,否则数据将作为字符串发送,就像您在fiddler中找到的那样。
通过这两项更改,请参阅我的请求和回复
$Splat = @{
Method = 'PUT'
Uri = 'https://api.us.onelogin.com/api/1/users/27697924/add_roles'
ContentType = "application/json"
Headers = @{authorization = "bearer:$token" }
Body = @{role_id_array = @(143175)} | ConvertTo-Json
}
try {Invoke-RestMethod @Splat -ErrorAction Stop }
catch {Failure}
以下是回复:
status
------
@{type=success; message=Success; error=False; code=200}
如果您认为PowerShell应该显示非200状态代码的实际服务器响应,那么请帮助关注Github上的这个open issue on the PowerShell项目页面。
添加您的反馈或竖起大拇指,我们可能会在将来的语言版本中对其进行更改。
此问题现已修复,自PowerShell v6.1起
答案 1 :(得分:0)
好的,所以我崩溃并安装了Fiddler,我想我已经做了些什么。 PowerShell cmdlet似乎不知道如何处理application / json contenttype的数组。我不确定XML会是这种情况,因为我还没有测试过。
我改变了主体以使用直接的json字符串,它起作用了:
$Body = "{ `"role_id_array`": [123456] }"
如果我使用一个哈希表,其值设置为这样的数组:
$Body = @{role_id_array = 115028,128732}
然后我会得到400故障响应。 Fiddler告诉我发生了什么 - 这是原始请求:
PUT https://api.us.onelogin.com/api/1/users/12345678/add_roles HTTP / 1.1 授权:持票人:3c93ae2-redacted- User-Agent:Mozilla / 5.0(Windows NT; Windows NT 6.3; en-US)WindowsPowerShell / 5.1.14394.1000 Content-Type:application / json 主持人:api.us.onelogin.com 内容长度:33 的 role_id_array = System.Object的%5B%5D 强> 的
请注意,数组未正确转换,而是将Invoke-RestMethod简单地折叠为typename定义,类似于Export-Csv处理数组属性值的方式。
所以我觉得我在使用PUT方法时遇到了问题,因为我的所有GET调用都在工作,但那是一个红色的鲱鱼。真正的问题是处理REST端点,该端点需要数组值的请求参数值。
编辑:我发现有人在2014年发布了此问题,但他的解决方法是将-ContentType参数设置为' application / json':Powershell v4 Invoke-RestMethod body sends System.Object
我已经完成了这个并且仍然遇到了同样的问题。这是一个错误吗?