217

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ペアまたはを使用しHttpClientても違いはありません。

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

4

10 に答える 10

481

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

System.Net.ServicePointManager.Expect100Continue = false;

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

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

于 2009-02-19T19:45:45.263 に答える
115

別の方法 -

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

<system.net>
    <settings>
        <servicePointManager expect100Continue="false" />
    </settings>
</system.net>
于 2011-09-09T07:34:17.663 に答える
31

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

  • HTTP 1.1 を認識しないプロキシを使用するようにエンド ユーザーのマシンが (インターネット設定で) 構成されている
  • クライアントは、HTTP 1.0 プロキシが理解できないものを送信することになります (一般的に、HTTPまたはリクエストExpectの一部としてのヘッダーは、ここの備考で説明されているように、リクエストを 2 つの部分に分けて送信するという標準プロトコル規則によるものです) 。POSTPUT

... 417 を生成します。

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

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

しかし、実際の問題は、自動生成されたコードが、HTTP 1.1 機能をやみくもに使用しても問題ないと想定していることです。これは誰もが理解していることです。特定の Web サービス プロキシに対するこの仮定を停止するには、この投稿に示されているようにオーバーライドする派生プロキシ クラスを作成することにより、デフォルトの1.1HttpWebRequest.ProtocolVersionからデフォルトのオーバーライドを変更できます。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 参照の追加ウィザードが吐き出したプロキシはどこにありますか。)


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

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 };
    }
}
于 2012-06-06T14:14:36.543 に答える
5

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

もしそうなら、この行:

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

は正しくありません。

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

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

編集:

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

Web サーバーが期待している、あなたが送信していない隠しフィールドがフォームにある可能性があります。

于 2009-02-19T18:01:21.597 に答える
4

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

于 2013-05-28T06:19:22.790 に答える
0

ネットワーク接続がリダイレクトされていないことを確認します。

間違った Wi-Fi を使用していて、Web リクエストが企業のログイン ページにリダイレクトされたときに、この問題が発生しました。

于 2020-11-06T01:04:16.050 に答える
0

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

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

于 2015-07-21T07:51:39.567 に答える
-1

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

  <system.net>
    <defaultProxy />
    <settings> <!-- 20130323 bchauvin -->
        <servicePointManager expect100Continue="false" />
    </settings>
  </system.net>
于 2013-03-24T22:58:47.833 に答える