HTTP POSTがエラーを返します:417「予期しないエラーが発生しました。」


212

URLにPOSTしようとすると、次の例外が発生します。

リモートサーバーがエラーを返しました:(417)予期された失敗。

これがサンプルコードです:

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.

HttpWebRequest/HttpWebResponseペアまたはan を使用しHttpClientても違いはありません。

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


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

2
クライアントがHTTP 1.0(のみ)プロキシサーバーを介して実行されているときに、この状態が発生しました。クライアント(設定のないasmxプロキシ)はHTTP 1.1リクエストを送信し、プロキシは(サーバーが関与する前に)プロキシが送信したものを拒否します。エンドユーザーが使用して、この問題を持っている必要があり、以下のコンフィグ解決することは、それは要求が理解プロキシに依存せずに生成される原因となるように、適切な回避策であるExpectとしてデフォルトで追加されるヘッダExpect100Continuetrue、デフォルトでは。
Ruben Bartelink

回答:


478

System.Net.HttpWebRequestは、この静的プロパティをfalseに設定して明示的に要求しない限り、すべての要求にヘッダー「HTTPヘッダー "Expect:100-Continue"」を追加します。

System.Net.ServicePointManager.Expect100Continue = false;

一部のサーバーはそのヘッダーを詰まらせ、表示されている417エラーを返します。

それを試してみてください。


5
クリスマスの翌日に突然動作しなくなったTwitterとやり取りするコードがありました。彼らはアップグレードや設定変更を行ったため、サーバーがそのヘッダーを詰まらせ始めました。修正を見つけるのは大変でした。
xcud

8
Jon Skeetがソリューションを投稿したスレッドで回答が受け入れられるようにしたので、さらに10ポイント獲得したと思います。
xcud 2009

1
ありがとう!これは、msdn.microsoft.com
Eugene

25
app.configでそのプロパティを指定することもできます:<system.net> <settings> <servicePointManager expect100Continue = "false" />。nahidulkibria.blogspot.com/2009/06/...
アンドレLuus

2
注:この設定はServiceReferencesにも適用され、私はWebReferencesを想定しています。
ミスター

114

別の方法 -

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

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

6
運用上の変更を行う必要があり、コード変更の準備ができていない場合に非常にうまく機能します。
dawebber 2013

1
構成のその行は何をしますか?
J86は、

31

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

  • エンドユーザーのマシンが(インターネット設定で)HTTP 1.1を理解しないプロキシを使用するように構成されている
  • クライアントは、HTTP 1.0プロキシが理解できないものを送信することになります(通常、ここでの解説で説明されているように、要求を2つの部分に送信する標準プロトコル規約によりExpect、HTTP POSTまたはPUT要求の一部としてのヘッダー)

... 417になります。

他の回答で説明されているように、Expect発生した特定の問題がヘッダーが問題の原因である場合、その特定の問題は、を介して2つの部分からなるPUT / POST送信を比較的グローバルにオフにすることで回避できますSystem.Net.ServicePointManager.Expect100Continue

ただし、これは根本的な問題を完全に修正するものではありません。スタックは、キープアライブなどのHTTP 1.1固有のものをまだ使用している可能性があります(多くの場合、他の回答は主なケースをカバーしています)。

しかし、実際の問題は、自動生成されたコードが、誰もが理解しているように、HTTP 1.1機能を盲目的に使用しても問題がないと想定していることです。特定のWebサービスプロキシのこの前提をやめるには、この投稿に示すようにオーバーライドする派生Proxyクラスを作成することHttpWebRequest.ProtocolVersionで、デフォルトの1.1からデフォルトのオーバーライドを変更できます。protected override WebRequest GetWebRequest(Uri uri)

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

MyWSWeb参照の追加ウィザードが表示するプロキシはどこにありますか。)


更新:これは私が本番環境で使用している実装です:

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
かなり前にこれを投稿したことは知っていますが、ルーベン、あなたは命の恩人です。私があなたの解決策に出会い、それが完全に機能するまで、この問題は私を夢中にさせてきました。乾杯!
Christopher McAtackney

1
@ChrisMcAtackneyどういたしまして。それは彼らにその時それを文書化する努力の価値があるように確かに見えました...最優先の問題になることの周辺を取り巻く一般的な問題は私がそれを適切に調査するまでちょうど私を悩ませました-それでもグーグルジュースはなかったようです問題のその側。そして、それをやるように押し付けたのは、ずっと前からのAttwood chapの投稿の1つでした。(このようなコメント付きの
賛成票

1
素晴らしい追加と例。ありがとう!
Fadi Chamieh、2014

5

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

もしそうなら、この行:

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

不正解です。

次のような2行が必要です。

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

編集:

さて、それは問題ではないので、これに取り組む1つの方法は、FiddlerやWiresharkなどを使用して、ブラウザーからWebサーバーに送信されているものを正常に監視し、それをコードから送信されているものと比較することです。.Netから通常のポート80に移動する場合でも、Fiddlerはこのトラフィックをキャプチャします。

フォーム上に、送信していないとWebサーバーが予期している他の非表示フィールドがおそらくあるでしょう。


3

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


2

Powershellの場合

[System.Net.ServicePointManager]::Expect100Continue = $false

1

HttpClient」を使用していて、使用できるすべてのプログラムに影響を与えるためにグローバル構成を使用したくない場合:

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

WebClient」を使用している場合、次の呼び出しでこのヘッダーを削除してみてください。

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

0

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

だから私が見つけることができる唯一の解決策は、エラーをキャッチし、ファイアウォール設定を手動で変更することをユーザーに通知することです。


-1

web.configアプローチは、IntApp Webサービス対応ルールへのInfoPathフォームサービス呼び出しに対して機能します。

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

2
stackoverflow.com/a/7358457/11635の dup ポイントを追加したい場合は、コメントしてください
Ruben Bartelink
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.