How do I get the body of a web request that returned 400 Bad Request from Invoke-RestMethod
当我运行以下语句
1 2 3 4 5 | Invoke-RestMethod"https://api.mysite.com/the/endpoint" ` -Body (ConvertTo-Json $data) ` -ContentType"application/json" ` -Headers $DefaultHttpHeaders ` -Method Post |
端点返回
1 2 3 4 5 6 | Invoke-WebRequest : The remote server returned an error: (400) Bad Request. At line:1 char:1 + Invoke-WebRequest"https://api.mysite.com/the/endpoint" -Body ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand |
如何获得响应的正文,这可能告诉我我发送的请求出了什么问题?
PowerShell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | try { Invoke-RestMethod"https://api.mysite.com/the/endpoint" ` -Body (ConvertTo-Json $data) ` -ContentType"application/json" ` -Headers $DefaultHttpHeaders ` -Method Post } catch { $streamReader = [System.IO.StreamReader]::new($_.Exception.Response.GetResponseStream()) $ErrResp = $streamReader.ReadToEnd() | ConvertFrom-Json $streamReader.Close() } $ErrResp |
根据Invoke-RestMethod文档,cmdlet可以根据收到的内容返回不同的类型。将cmdlet输出关联到变量(
如果
编辑:
好的,我明白了,这很明显:)。 Invoke-RestMethod引发错误,因此让我们赶上它:
1 2 3 4 5 6 7 8 9 10 | try{$restp=Invoke-RestMethod (...)} catch {$err=$_.Exception} $err | Get-Member -MemberType Property TypeName: System.Net.WebException Name MemberType Definition ---- ---------- ---------- Message Property string Message {get;} Response Property System.Net.WebResponse Response {get;} Status Property System.Net.WebExceptionStatus Status {get;} |
这就是您所需要的,尤其是在WebResponse对象中。
我列出了3个引人注目的属性,还有更多。同样,如果您存储的是
$ RespErr在我的案例中将包含有关BadRequest的更多详细信息
1 | $responce = Invoke-RestMethod -Uri https://localhost:44377/explore/v2/Content -Method Post -Body $PostData -Headers $header -ErrorVariable RespErr; |
$ RespErr;
1 | {"error":{"code":"","message":"The FavoriteName field is required." } } |
看来它仅在localhost中有效,我尝试在我的实际服务器上不起作用。
另一种尝试的方法是
1 2 3 4 5 6 7 8 9 10 11 12 13 | try{ $response ="" $response = Invoke-WebRequest -Uri https://contentserverint-mhdev.azurewebsites.net/apis/explore/v2/Content?overwrite=true -Method Post -Body $PostData -Headers $header -ErrorVariable RespErr #$response = Invoke-RestMethod -Uri https://localhost:44377/explore/v2/Content?overwrite=true -Method Post -Body $PostData -Headers $header -ErrorVariable RespErr Write-Host"Content created with url="$response.value[0] } catch [System.Net.WebException] { $respStream = $_.Exception.Response.GetResponseStream() $reader = New-Object System.IO.StreamReader($respStream) $respBody = $reader.ReadToEnd() | ConvertFrom-Json $respBody; } |
对我来说,它仅在Pester上下文中有效,在读取之前将流Position设置为0时。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | $statusCode = $null $responseBody = $null try { $response = Invoke-RestMethod -Method GET -Uri"$($apiPrefix)$($operation)" -Headers $headers } catch [System.Net.WebException] { $statusCode = $_.Exception.Response.StatusCode $respStream = $_.Exception.Response.GetResponseStream() $reader = New-Object System.IO.StreamReader($respStream) $reader.BaseStream.Position = 0 $responseBody = $reader.ReadToEnd() | ConvertFrom-Json } $statusCode | Should Be $Expected $responseBody | Should Not Be $null |
如果您只是在响应
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # Place the trap within your chosen scope (e.g. function or script) trap [Net.WebException] { continue; } # Exceptions are no longer thrown here $response = Invoke-WebRequest $endpoint # Check if last command failed if (!$?) { # $error[0] now contains the ErrorRecord of the last error (in this case from Invoke-WebRequest) # Note: $response should be null at this point # Due to the magic of Microsoft.PowerShell.Commands.InvokeWebRequestCommand.WebCmdletWebResponseException # we can get the response body directly from the ErrorDetails field $body = $error[0].ErrorDetails.Message # For compatibility with $response.StatusCode lets cast to int $statusCode = [int] $error[0].Exception.Response.StatusCode } |
据我所知,