1

同じコードを使用してサード パーティの Web サイトに "ログイン" する ASP.NET Web サイトと Web サービスが多数あります。これには基本的に、WebRequest を使用して Web サイトのログイン ページに認証情報で HTTP POST を実行し、結果の Cookie を CookieContainer に保存し、その CookieContainer を後続の WebRequest で使用して、サード パーティの Web サイトのページに対して Web サイトを承認することが含まれます。

コードは基本的に次のとおりです。

    public LoginResults Login()
    {
        // Create the webrequest
        var request = CreateInitialWebRequest(LOGIN_URL);
        request.AllowAutoRedirect = false;

        // Set the cookiecontainer, which will be filled with the authentication cookies
        this.cookieContainer = new CookieContainer();
        request.CookieContainer = this.cookieContainer;

        // Set the username and pw in a HTTP POST call
        SetPostContent(request, string.Format(LOGIN_PARAMETERS, this.Username, this.Password));

        // Read the response
        using (var httpWebResponse = (HttpWebResponse)request.GetResponse())
        {
            using (var responseStream = httpWebResponse.GetResponseStream())
            {
                 // Omitted:
                 // read response and determine if login was successful
            } 
        }
    }

    private HttpWebRequest CreateInitialWebRequest(string uri)
    {
        var request = (HttpWebRequest)WebRequest.Create(uri);
        ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
        return request;
    }

    private HttpWebRequest CreateWebRequest(string uri)
    {
        var request = this.CreateInitialWebRequest(uri);
        request.CookieContainer = cookieContainer;
        request.Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-ms-application, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-ms-xbap, application/x-shockwave-flash, */*";
        request.UserAgent = "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506; .NET CLR 3.5.21022)";
        request.Method = "GET";
        request.Timeout = 10000; // 10 sec
        return request;
    }

    private static void SetPostContent(HttpWebRequest req, string postData)
    {
        req.Method = "POST";
        byte[] bytes = new ASCIIEncoding().GetBytes(postData);
        req.ContentType = "application/x-www-form-urlencoded";
        req.ContentLength = (long)bytes.Length;
        ((WebRequest)req).GetRequestStream().Write(bytes, 0, bytes.Length);
        ((WebRequest)req).GetRequestStream().Close();
    }

このコードは長い間 (数か月、半年以上) 機能しています。今週末から、非常に頻繁に失敗するようになりました (私が推定する 90% の確率ですが、100% の確率ではありません)。私が見続けるエラーは次のとおりです: System.Net.WebException: 基になる接続が閉じられました: 送信時に予期しないエラーが発生しました。---> System.IO.IOException: 予期しないパケット形式のため、ハンドシェイクが失敗しました。 スタック トレースは次のとおりです。

System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: The handshake failed due to an unexpected packet format.
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.TlsStream.CallProcessAuthentication(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.ConnectStream.WriteHeaders(Boolean async)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
at System.Net.HttpWebRequest.GetRequestStream()
at iRacingForumService.HttpPost.SetPostContent(HttpWebRequest req, String postData)
at iRacingForumService.HttpPost.Login()

このエラーをグーグルで検索すると、私が見続ける唯一の解決策は、WebRequest の KeepAlive プロパティを無効にするか、ProtocolVersion を HttpVersion10 に設定することです。両方を(可能な限りすべての組み合わせで)試しましたが、何も役に立ちません。

エラーは常に表示されるわけではありませんが、表示された場合は、好きなだけ試してみることができます。何度も何度もエラーが発生し続けます。数分間放置して再試行すると、機能する可能性があります (一度機能すると、しばらくは機能し続けます)。

奇妙な点は、私が何も変更していないことです。このコードは何ヶ月も問題なく実行されています。サード パーティの Web サイトが最後に何かを変更したか、私の Web ホスティング プロバイダーが何かを変更した可能性は十分にあります。しかし、この問題を解決するために何かできることがある場合に備えて、何か間違ったことをしていないかどうか尋ねたいと思いました.

サード パーティの Web サイト (おそらく応答が得られない) または Web ホスティングに連絡することもできますが、このエラーをそれらにスローしてもおそらく役に立たないため、正確に何が問題なのかをよりよく理解する必要があります。

それで、私にできることはありますか、それとも私のすべてのウェブサイトで突然このエラーが表示されるのには正当な理由がありますか (それらはすべて同じサードパーティのサイトに接続しています)?

ありがとう

4

1 に答える 1

0

これは断続的に発生するため、サーバー管理者に連絡して、何が起こっているのかを調べる必要がある場合があります。負荷、設定ミス、またはその他のネットワークの問題が原因で、サーバーが単に接続を拒否または終了する可能性があります。

于 2013-04-17T18:37:49.637 に答える