【问题标题】:Error Handling in System.Net.HttpWebRequest::GetResponse()System.Net.HttpWebRequest::GetResponse() 中的错误处理
【发布时间】:2012-03-03 05:41:26
【问题描述】:

我有一个 Powershell 脚本,它使用 System.Net.HttpWebRequest 与远程主机通信。

我创建请求,相应地设置属性并调用getresponse()getresponsestream() 以从服务器读取整个响应到一个字符串。只要服务器以“200 OK”消息响应,就可以正常工作。

如果服务器响应“400 错误请求”或任何其他错误代码,getresponse()getresponsestream() 将抛出异常并且不返回任何内容。我的问题是我需要的响应标头中包含更详细的错误信息,因此我可以自己进行错误处理。

我如何才能检索到这个 400 Bad Request 信号?

【问题讨论】:

  • 您是否已经捕获了异常对象并查看了 $_.Exception.Message 属性?并探索了 $_.Exception 对象?

标签: .net powershell httpwebrequest httpwebresponse


【解决方案1】:

编辑:起初我误解了这个问题,但事实证明您可以使用HttpWebResponse.GetResponseHeader()方法检索响应头。如果发生异常,HttpWebRequest.GetResponse()方法返回$null,你必须使用这段代码来检索HttpWebResponse对象,这样你就可以调用GetResponseHeader()

# If an exception occurs, get the HttpWebResponse object from the WebException object
$HttpWebResponse = $Error[0].Exception.InnerException.Response;

我很确定您会想要坚持使用 System.Net.HttpWebRequest 而不是 System.Net.WebClient 对象。这是一个示例,类似于您可能已经拥有的示例:

# Create a HttpWebRequest using the Create() static method
$HttpWebRequest = [System.Net.HttpWebRequest]::Create("http://www.google.com/");

# Get an HttpWebResponse object
$HttpWebResponse = $HttpWebRequest.GetResponse();

# Get the integer value of the HttpStatusCode enumeration
Write-Host -Object $HttpWebResponse.StatusCode.value__;

GetResponse() 方法返回一个HttpWebResponse 对象,该对象具有一个名为StatusCode 的属性,该属性指向HttpStatusCode .NET 枚举中的一个值。一旦获得对枚举的引用,我们就使用value__ 属性来获取与返回的枚举值关联的整数。

如果您从GetResponse() 方法中得到一个空值,那么您需要在您的catch {..} 块中读取最新的错误消息。 Exception.ErrorRecord 属性应该是最有帮助的。

try {
  $HttpWebResponse = $null;
  $HttpWebRequest = [System.Net.HttpWebRequest]::Create("http://www.asdf.com/asdf");
  $HttpWebResponse = $HttpWebRequest.GetResponse();
  if ($HttpWebResponse) {
    Write-Host -Object $HttpWebResponse.StatusCode.value__;
    Write-Host -Object $HttpWebResponse.GetResponseHeader("X-Detailed-Error");
  }
}
catch {
  $ErrorMessage = $Error[0].Exception.ErrorRecord.Exception.Message;
  $Matched = ($ErrorMessage -match '[0-9]{3}')
  if ($Matched) {
    Write-Host -Object ('HTTP status code was {0} ({1})' -f $HttpStatusCode, $matches.0);
  }
  else {
    Write-Host -Object $ErrorMessage;
  }

  $HttpWebResponse = $Error[0].Exception.InnerException.Response;
  $HttpWebResponse.GetResponseHeader("X-Detailed-Error");
}

http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.aspx

http://msdn.microsoft.com/en-us/library/system.net.httpstatuscode.aspx

http://msdn.microsoft.com/en-us/library/system.net.httpwebresponse.aspx

【讨论】:

  • 3 位 HTTP 状态码对我没有任何作用。我需要从远程主机的响应中访问自定义标头“X-Detailed-Error”。是否有某种方法可以调用 getresponse() 并让它返回一个 webresponse 对象,而不管状态码是什么?
  • 我已经更新了示例。在发生异常的情况下,必须通过$Error[0].Exception.InnerException.Response获取HttpWebResponse对象,然后调用GetResponseHeader("X-Detailed-Error");方法。
【解决方案2】:

曾经尝试过 try 和 catch 语句吗?这对我来说很好。

例如:

$webclient = new-object system.net.webclient
try {
    $domain = $webclient.downloadstring("http://xrsolis.com") # get a non existent domain
} catch {
    write-host "domain inaccessible"
}

【讨论】:

  • 这并没有真正帮助,因为它不允许我访问来自服务器的完整响应。在服务器发送通用 HTTP 状态代码后,它还会发送一个自定义标头(X-Detailed-Error),其中包含未处理请求的确切原因。我需要能够访问该标题。 $_.Exception 返回的异常消息与我在没有 catch 语句的控制台中看到的相同(使用“0”参数调用“GetResponse”的异常:“远程服务器返回错误:(403) Forbidden。”)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-27
相关资源
最近更新 更多