Invoke-RestMethod调用仅在下面返回非常无用的异常,并且(据我所知)不允许您收集正文内容(fiddler跟踪结果中显示的JSON对象)。这似乎是一个非常糟糕的实现,如果是这样,因为http 500定义非常具体,客户端应该返回响应的主体以帮助排除故障...我错过了什么?
invoke-restmethod -method Post -uri "https://api-stage.enviance.com/ver2/EqlService.svc/eql" -Body (ConvertTo-Json $eqlhash) -Headers @{"Authorization"="Enviance $session"}
invoke-restmethod:远程服务器返回错误:(500) 内部服务器错误。在行:1 char:9 ...
下面的提琴手追踪
HTTP / 1.1 500内部服务器错误连接:关闭日期:9月12日星期四 2013 17:35:00 GMT服务器:Microsoft-IIS / 6.0 X-Powered-By:ASP.NET X-AspNet-Version:2.0.50727 EnvApi-Version:2.0,2.0 EnvApi-Remaining-Calls:994,994 EnvApi-Remaining-Interval:2684,2684 Cache-Control:no-cache Pragma:no-cache Expires:-1 Content-Type: 文本/ CSV;字符集= UTF-8
{“errorNumber”:0,“message”:“当前用户无权检索 表'CustomFieldTemplate'“}
中的数据
答案 0 :(得分:75)
另一个答案确实可以为您提供响应,但您需要一个额外的步骤来获取响应的实际主体,而不仅仅是标题。这是一个片段:
try {
$result = Invoke-WebRequest ...
}
catch {
$result = $_.Exception.Response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($result)
$reader.BaseStream.Position = 0
$reader.DiscardBufferedData()
$responseBody = $reader.ReadToEnd();
}
答案 1 :(得分:24)
虽然是旧线程,但这里是对cmdlet Invoke-WebRequest和Invoke-RestMethod的问题的答案。
这个人困扰了我很长一段时间。由于所有4xx和5xx响应都生成异常,您必须捕获该异常,然后您可以从那里提取响应。像这样使用它:
$resp = try { Invoke-WebRequest ... } catch { $_.Exception.Response }
现在$ resp总是包含你喜欢的一切。
答案 2 :(得分:12)
搜索我的问题的答案我找到了这个帖子。
这些解决方案对我有用,但我不得不添加两个新行:
$reader.BaseStream.Position = 0
$reader.DiscardBufferedData()
谢谢!
答案 3 :(得分:7)
此解决方案不再适用于PowerShell 6 - 它不支持GetResponseStream()
。而是使用
try {
$result = Invoke-WebRequest ...
}
catch {
$_.ErrorDetails.Message
}
我写了一个简短的帮助函数来支持PowerShell 6及更早版本:
function ParseErrorForResponseBody($Error) {
if ($PSVersionTable.PSVersion.Major -lt 6) {
if ($Error.Exception.Response) {
$Reader = New-Object System.IO.StreamReader($Error.Exception.Response.GetResponseStream())
$Reader.BaseStream.Position = 0
$Reader.DiscardBufferedData()
$ResponseBody = $Reader.ReadToEnd()
if ($ResponseBody.StartsWith('{')) {
$ResponseBody = $ResponseBody | ConvertFrom-Json
}
return $ResponseBody
}
}
else {
return $Error.ErrorDetails.Message
}
}
try {
$result = Invoke-WebRequest ...
}
catch {
ParseErrorForResponseBody($_)
}
答案 4 :(得分:0)
请注意,$_.ErrorDetails.Message
不是原始响应正文,它是Florial Feldhaus对答案提供者的扩展。
HTML标记删除正则表达式用于使响应更易于阅读github link。由于流位于1535行,因此目前无法检索原始响应正文。
解决方法是使用dotnet HttpClient
获取原始响应,而不是使用Invoke-WebRequest
cmdlet
$url = "http://localhost"
$client = [System.Net.Http.HttpClient]::new()
$request = [System.Net.Http.HttpRequestMessage]::new()
$request.Content = [System.Net.Http.StringContent]::new("Hello World", [System.Text.Encoding]::UTF8, "plain/text")
$result = $client.SendAsync($request).GetAwaiter().GetResult()
$content = $result.Content.ReadAsStringAsync().GetAwaiter().GetResult()
Write-Verbose $content -Verbose
powershell核心github问题是here
答案 5 :(得分:0)
我一直在专门使用Invoke-RestMethod-由于它可能是Invoke-WebRequest的包装,因此以下信息可能会有用。
您需要捕获异常,然后像这样从“响应”中获取响应流。
try
{
$response = Invoke-RestMethod Method Get uri "$($uri)" -Headers $headers
return $response
}
catch
{
Write-Host "Exception details: "
$e = $_.Exception
Write-Host ("`tMessage: " + $e.Message)
Write-Host ("`tStatus code: " + $e.Response.StatusCode)
Write-Host ("`tStatus description: " + $e.Response.StatusDescription)
Write-Host "`tResponse: " -NoNewline
$memStream = $e.Response.GetResponseStream()
$readStream = New-Object System.IO.StreamReader($memStream)
while ($readStream.Peek() -ne -1) {
Write-Host $readStream.ReadLine()
}
$readStream.Dispose();
}