当我运行下面的语句
Invoke-RestMethod "https://api.mysite.com/the/endpoint" `
-Body (ConvertTo-Json $data) `
-ContentType "application/json" `
-Headers $DefaultHttpHeaders `
-Method Post
端点返回400 Bad Request
,这将导致PowerShell将显示以下不那么有用信息:
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
我如何获得响应的身体,这可能会告诉我什么是错的我发送的请求?
据调用-RestMethod文档,小命令可以返回根据它接收到的内容不同的类型。 Assing小命令输出给一个变量( $resp = Invoke-RestMethod (...)
然后检查如果类型是HtmlWebResponseObject
( $resp.gettype()
然后你就会在您的处置许多特性,如BaseResponse,内容及的StatusCode。
如果$resp
是一些其他类型(字符串,psobject并极有可能为空在这种情况下),似乎是错误信息The remote server returned an error: (400) Bad Request
是响应主体,从HTML只提(我测试了这个关于我的一些方法),甚至截断。 如果要提取它,使用通用参数来存储错误信息运行cmdlet: Invoke-RestMethod (...) -ErrorVariable RespErr
,你就会有它在$RespErr
变量。
编辑:
好吧,我知道了,这是很明显的:)。 调用-RestMethod抛出一个错误,所以让我们正好赶上它:
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个属性是吸引眼球,还有更多。 此外,如果你存储$_
,而不是$_.Exception
可能会有一些性能的PowerShell已经提取了你,但我并不指望什么比更有意义.Exception.Response
。
有使用PowerShell一个已知的问题Invoke-WebRequest
和Invoke-RestMethod
其中壳吃响应体时的状态代码是错误(或4XX 5XX)。 听起来像是你正在寻找只是这种方式被蒸发JSON内容。 您可以使用您的catch块获取响应正文$_.Exception.Response.GetResponseStream()
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
$ RespErr将有关于错误请求的详细信息,在我的情况下,其
$responce = Invoke-RestMethod -Uri https://localhost:44377/explore/v2/Content -Method Post -Body $PostData -Headers $header -ErrorVariable RespErr;
$ RespErr;
{ "error":{ "code":"","message":"The FavoriteName field is required." } }
它看起来像它只能在本地主机,我想用我的实际的服务器没有奏效。
另一种方式是尝试这个
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;
}
如果你只是响应后StatusCode
和Content
这里没有很多杂乱的try / catch和响应流的人工抄表的解决这一问题的新方法:
# 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
}
据我所知道的, ErrorRecord.ErrorDetails.Message
包含准确相当于Microsoft.PowerShell.Commands.WebResponseObject.Content
将得到退还给你的一个成功调用属性Invoke-WebRequest
,只是不必的麻烦做一切GetResponseStream()
爵士。
对我来说,只有在一个纠缠背景下工作过,流位置设置为0时,阅读它之前。
$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
文章来源: How do I get the body of a web request that returned 400 Bad Request from Invoke-RestMethod