2012-03-03 61 views
2

我有一个Powershell脚本,它使用System.Net.HttpWebRequest与远程主机通信。错误处理System.Net.HttpWebRequest :: GetResponse()

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

如果服务器有一个“400错误的请求”或任何其他错误代码,getresponse()getresponsestream()抛出异常和返回任何响应。我的问题是有更详细的错误信息包含在我需要的响应头中,所以我可以做我自己的错误处理。

我该如何检索这个400错误请求信号?

+0

你是否已经捕捉到的异常物体,看着$ _。Exception.Message财产?并探讨了$ _。Exception对象? – 2012-03-03 06:58:30

回答

5

编辑:我误解了这个问题,在第一,但事实证明,你可以通过使用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

+0

3位数字的HTTP状态码对我没有任何帮助,我需要从远程主机的响应中访问自定义头文件”X-Detailed-Error“。是不是有一些方法可以调用getresponse()并让它返回一个webresponse对象,无论状态码是什么? – Justin 2012-03-03 16:46:54

+0

我更新了这个例子,在发生异常的情况下,你必须使用'$ Error [0] .Exception.InnerException.Response'来获取'HttpWebResponse'对象。 ,然后你可以调用'GetResponseHeader(“X-Detailed-Error”);'方法 – 2012-03-03 17:00:10

+0

这很好,谢谢你 – Justin 2012-03-03 18:02:06

0

有没有试过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" 
} 
+0

这并没有什么帮助,因为它不允许我访问服务器的完整响应。服务器发送公共HTTP状态码后,它还会发送一个自定义标题(X-Detailed-Error),其中包含未处理该请求的确切原因。我需要能够访问该标题。 $ _。异常返回异常消息,我将在控制台中看到没有catch语句( 异常情况下调用“GetResponse”和“0”参数:“远程服务器返回错误:(403)Forbidden。“) – Justin 2012-03-03 15:23:45