2009-02-19 30 views
193

それは、次の例外が発生:HTTP POSTエラー:417 "Expectation Failed"が返されます。私はURLに投稿しようとすると

The remote server returned an error: (417) Expectation Failed.

ここではサンプルコードです:HttpWebRequest/HttpWebResponseペアまたはHttpClientを使用して

var client = new WebClient(); 

var postData = new NameValueCollection(); 
postData.Add("postParamName", "postParamValue"); 

byte[] responseBytes = client.UploadValues("http://...", postData); 
string response = Encoding.UTF8.GetString(responseBytes); // (417) Expectation Failed. 

は違いはありません。

この例外の原因は何ですか?

+2

アプリケーションがプロキシサーバー経由で通信するときに問題が発生しているようです。私が書いた.NETアプリケーションは、インターネットに直接接続されていても、プロキシサーバーの背後にあったときには機能しませんでした。 –

+2

クライアントがHTTP 1.0(のみ)プロキシサーバーを実行しているときにこの条件を確認します。クライアント(構成を持たないasmxプロキシ)がHTTP 1.1要求を送信していて、プロキシがサーバーに参加する前にプロキシが送信した内容を拒否します。エンドユーザーがこの問題を抱えている場合、[config solution below](http://stackoverflow.com/a/7358457/11635)を使用すると、プロキシの理解に依存せずにリクエストが生成されるため、適切な回避策ですデフォルトでは 'Expect100Continue'として追加される' Expect'ヘッダはデフォルトで 'true'です。 –

答えて

445

System.Net.HttpWebRequestは、ヘッダ追加「HTTPヘッダ 『を期待:100-Continue』を」すべての要求に明示的にfalseにthis static propertyを設定することではないにそれを聞いていない限り:

一部のサーバーがオンにチョークあなたが見ている417エラーを返します。

そのショットを付けます。

+68

よろしくお願いします。 – Moose

+5

私は、Twitterに話したコードを、クリスマス後に突然仕事をやめたことがありました。彼らはアップグレードや設定の変更を行って、サーバがそのヘッダを窒息させ始める原因となりました。修正を見つけるのは苦痛でした。 – xcud

+7

私は、Jon Skeetが解決策を投稿したスレッドで受け入れられる回答を得るために追加の10ポイントを拾ったと思います。 – xcud

5

エミュレートしようとしているフォームには、usernameとpasswordという2つのフィールドがありますか?

もしそうなら、この行:

postData.Add("username", "password"); 

が正しくありません。

あなたのような二行必要があります:それは問題ではないので、これに対処する一つの方法が何であるかを見るためにバイオリンやWiresharkのようなものを使用することで、

オーケー:

postData.Add("username", "Moose"); 
postData.Add("password", "NotMoosespasswordreally"); 

は、[編集]をブラウザからWebサーバーに正常に送信され、コードから送信されているものと比較します。 .Netから通常のポート80に行く場合、Fiddlerは引き続きこのトラフィックをキャプチャします。

Webサーバーが送信しないと予想しているフォームに、おそらく他の隠しフィールドがあります。

109

もう一つの方法 -

、アプリケーションの設定ファイルの構成セクションに次の行を追加します。

<system.net> 
    <settings> 
     <servicePointManager expect100Continue="false" /> 
    </settings> 
</system.net> 
+5

操作の変更を加えなければならず、コード変更の準備ができていないときはうまく動作します。 – dawebber

+0

configの行は何をしますか? – Ciwan

30

これと同じような状況とエラーはまた、デフォルトのウィザード生成されたSOAP Webサービスプロキシで発生する可能性がある(ありませんWCF System.ServiceModelスタックの場合も100%)実行時:

  • エンドユーザーHTTP 1.1を理解していないプロキシを使用するように(インターネット設定で)設定されています
  • HTTP 1.0プロキシが理解できないものをクライアントが送信します(一般にPOSTまたはPUT要求の一部としてExpectヘッダー)。要求を2つの部分に送信する標準的なプロトコルの慣習に変更する。as covered in the Remarks here

... 417を生成する。

Expectヘッダーが原因で問題が発生した場合は、2つの部分からなるPUT/System.Net.ServicePointManager.Expect100ContinueによるPOST送信

しかし、これは完全な根本的な問題が解決しない - (多くの場合、他の回答には、メインケースをカバーんが。)スタックは、まだなどキープアライブなどのHTTP 1.1の特定のものを使用している可能性があり

をしかし実際の問題は、自動生成されたコードでは、誰もが理解しているように、HTTP 1.1の機能を使って盲目的に行くことができると仮定しているということです。 MyWSがプロキシである

public class MyNotAssumingHttp11ProxiesAndServersProxy : MyWS 
{ 
    protected override WebRequest GetWebRequest(Uri uri) 
    { 
     HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(uri); 
     request.ProtocolVersion = HttpVersion.Version10; 
     return request; 
    } 
} 

( - :特定のWebサービスプロキシのこの仮定を停止するには、一つはprotected override WebRequest GetWebRequest(Uri uri)as shown in this postをオーバーライドする派生プロキシクラスを作成することによって、1.1のデフォルトからHttpWebRequest.ProtocolVersionの基礎となるデフォルトを上書き変更することができますWeb参照ウィザードはあなたに吐き出し追加)


UPDATEを:。

class ProxyFriendlyXXXWs : BasicHttpBinding_IXXX 
{ 
    public ProxyFriendlyXXXWs(Uri destination) 
    { 
     Url = destination.ToString(); 
     this.IfProxiedUrlAddProxyOverriddenWithDefaultCredentials(); 
    } 

    // Make it squirm through proxies that don't understand (or are misconfigured) to only understand HTTP 1.0 without yielding HTTP 417s 
    protected override WebRequest GetWebRequest(Uri uri) 
    { 
     var request = (HttpWebRequest)base.GetWebRequest(uri); 
     request.ProtocolVersion = HttpVersion.Version10; 
     return request; 
    } 
} 

static class SoapHttpClientProtocolRealWorldProxyTraversalExtensions 
{ 
    // OOTB, .NET 1-4 do not submit credentials to proxies. 
    // This avoids having to document how to 'just override a setting on your default proxy in your app.config' (or machine.config!) 
    public static void IfProxiedUrlAddProxyOverriddenWithDefaultCredentials(this SoapHttpClientProtocol that) 
    { 
     Uri destination = new Uri(that.Url); 
     Uri proxiedAddress = WebRequest.DefaultWebProxy.GetProxy(destination); 
     if (!destination.Equals(proxiedAddress)) 
      that.Proxy = new WebProxy(proxiedAddress) { UseDefaultCredentials = true }; 
    } 
} 
:ここで私は生産に使用している独自の実装があります
+2

あなたがこれをかなり前に投稿したことを知っていますが、Ruben、あなたは命の恩人です。この問題は、私があなたのソリューションに出くわすまで私を夢中にさせてくれました。乾杯! –

+1

@ChrisMcAtackneyよろしくお願いします。それは間違いなくその時にそれを文書化する努力の価値があるように見えました...一般的な問題は、最優先の問題になるの周りに設定し、私はそれを適切に調査するまで私を悩ませました - しかし、問題の側。それは私がそれをやるように押し付けた途中のAttwoodチャップのポストの一つでした。 (このようなコメントを持つupvoteは素晴らしいです) –

+1

素敵な追加と例。ありがとう! –

0

Web.configアプローチは、InfoPathフォームサービスがIntApp Webサービス対応ルールを呼び出す場合に機能します。プロキシ側から

<system.net> 
    <defaultProxy /> 
    <settings> <!-- 20130323 bchauvin --> 
     <servicePointManager expect100Continue="false" /> 
    </settings> 
    </system.net> 
+2

dup of http://stackoverflow.com/a/7358457/11635ポイントを追加したい場合は、そこにコメントしてください –

3

ソリューション、私は、SSLハンドシェイクプロセスでいくつかの問題に直面し、私は、httpd.conf SetEnv force-proxy-request-1.0 1でこの引数を設定することで、問題を解決するために、HTTP/1.0を使用して要求を送信するために私のプロキシサーバを強制しなければなりませんでした SetEnv proxy-nokeepalive 1私のクライアントアプリケーションがHTTP/1.1を使用していて、プロキシがHTTP/1.0を使用するようになったので、417エラーに直面した後、このパラメータはプロキシ側のhttpd.confにこのパラメータを設定することで解決されましたRequestHeader unset Expect earlyクライアント側で何かを変更するには、これが役立つことを願っています。

0

私の状況では、このエラーは、クライアントのコンピュータに厳格なファイアウォールポリシーが設定されている場合にのみ発生します。これにより、プログラムがWebサービスと通信できなくなります。

解決策は、エラーをキャッチして、ユーザーに手動でファイアウォール設定を変更するよう知らせることです。

1

あなたは「のHttpClient」を使用している、とあなたはあなたが使用できるプログラムすべてに影響を与えるために、グローバルコンフィギュレーションを使用しない場合:

HttpClientHandler httpClientHandler = new HttpClientHandler(); 
httpClient.DefaultRequestHeaders.ExpectContinue = false; 

私はあなたが「WebClientの」Iを使用していますあなたが呼び出すことによって、このヘッダを削除しようとすることができると思う:PowerShellの

var client = new WebClient(); 
client.Headers.Remove(HttpRequestHeader.Expect); 
0

それは

です
関連する問題