2016-03-29 13 views
8

小さなPowerShellスクリプトを書いて、サーバーにリクエストを送信し、簡単なXML結果を返します。 、本当にシンプルだし、それが失敗するために、私は見ることができない理由はありませんInvoke-WebRequestとInvoke-RestMethodが同時に失敗し、成功するのはなぜですか?

のPowerShellスクリプト

$xml = "<?xml version='1.0' encoding='utf-8'?><Search><ID>278A87E1-1BC2-4E19-82E9-8BBE31D67D20</ID></Search>" 
$response = Invoke-RestMethod -Method Post -Uri "http://localhost/search" -ContentType "application/xml" -Body $xml 

。私もInvoke-WebRequestでスクリプトを試してみましたが、どちらも失敗します。返されるエラーはInvoke-RestMethod : Value cannot be null. Parameter name: nameです。奇妙なことは、Wiresharkでこれを監視すると、接続が表示され、POSTが表示され、サーバーからの結果がすべて表示されるようになりますが、コマンドレットは失敗していると言います(そして、戻りコードは200 )。

-OutFileパラメータを使用してInvoke-WebRequest/Invoke-RestMethodを実行すると、エラーなしで正常に実行され、結果が指定されたファイルに保存されます。 -OutVariableが不思議に思っている場合に備えて失敗します。

結果は、XMLファイルで、ヘッダは、それがXMLであり、XMLが正しくフォーマットされていることを指定します。

結果とき

<?xml version="1.0" encoding="UTF-8" ?> 
<Result version="1.0" xmlns="urn:xmlns-org"> 
    <searchID>{278a87e1-1bc2-4e19-82e9-8bbe31d67d20}</searchID> 
    <responseStatus>true</responseStatus> 
    <responseStatusStrg>MORE</responseStatusStrg> 
    <numOfMatches>40</numOfMatches> 
</Result> 

成功Invoke-XXXコマンドレットがエラーを返していると私はそれを修正するために何ができるの理由を誰もが知っていますか?繰り返しますが、-OutFileパラメータを使用すると完全に正常に動作し、失敗してもスクリプトとサーバーの間の適切な会話がWiresharkに表示されます。私は-Verboseを使用する場合

また、それは私に次のように伝えます:

X-byteは応答の実際のサイズですが、それは明らかにサーバーに送信されたデータに応じて、各応答と異なり
VERBOSE: POST http://localhost/search with -1-byte payload 
VERBOSE: received X-byte response of content type application/xml; charset="UTF-8" 

。コマンドレットが失敗するのは間違いですが、データで応答を受け取り、-1-byteペイロードを送信したと言います。

答えて

7

私は先に行って、Invoke-WebRequestレットコードに見て、それがこの特定のエラーで失敗している理由が分かりました。

それはSystem.Globalization.EncodingTable.GetCodePageFromNameへの呼び出しに失敗しています。エンコードはその関数にパラメータとして渡され、エンコードはContent-Typeヘッダーを通じてコマンドレットから取得されます。このサーバーの場合、Content-TypeはContent-Type: application/xml; charset="UTF-8"という応答で返されました。

charsetに値をラップするための引用符は標準ではないため、コマンドレットは有効なUTF-8ではなく"UTF-8"と解釈します。コマンドレットは"UTF-8"を関数に渡し、関数は指定されたエンコーディングが無効であることを示す例外をスローします。これは最終的な例外で報告されたものであれば問題ありませんが、はるかに意味があります。

無効符号化例外がMicrosoft.PowerShell.Commands.ContentHelper.GetEncodingOrDefault関数によって捕捉され、例外ハンドラで再びしかし、パラメータnameの最終ArgumentNullExceptionもたらすヌルパラメータでGetEncodingを呼び出します。

Microsoft.PowerShell.Commands.ContentHelper.GetEncodingOrDefault自体がGetEncoding

if (name==null) { 
    throw new ArgumentNullException("name"); 
} 

のPowerShellから呼び出され

internal static Encoding GetEncodingOrDefault(string characterSet) 
{ 
    string name = string.IsNullOrEmpty(characterSet) ? "ISO-8859-1" : characterSet; 
    try 
    { 
    return Encoding.GetEncoding(name); 
    } 
    catch (ArgumentException ex) 
    { 
    return Encoding.GetEncoding((string) null); 
    } 
} 

catch文の内側GetEncodingへの呼び出しがGetCodePageFromName内で次のコードをトリガー技術的には無効な値なのでこれを適切に処理していますが、Trim("\"")だけで安全です。

+0

私はこの問題をPython 2.7の 'SimpleHTTPServer'で実行しています。 – Kupiakos

+0

根本原因を発見してくれてありがとう。 PowerShell(WMF)5.1がインストールされた、完全にパッチが当てられたWindows Server 2012 R2ボックスでこのマニフェストを確認しました。 同じコードをWindows 10またはWindows Server 2016に適用しても問題はありません。解決策に見えないので、非常に残念です。 – Lewis

関連する問題