0

それだけの価値があるため、既存の ASP.NET Web アプリケーションで自分自身を認証するコンソール アプリケーションを取得することができました。ビューステート情報を含むログイン ページに POST リクエストを送信することで、ログイン ページを模倣するだけです (ブラウザがリクエストを行ったかのように)。

次に、応答として返された Cookie を CookieContainer でキャッチします。

その後、アプリケーションは同じページに対して複数のリクエストを行います (これには承認が必要です)。ページは何らかの作業を行い、サーバーにファイルを書き出します。

私が遭遇している問題は、偽のログインの後、最初の 2 つの要求が問題なく通過することです。3 番目の要求は、応答を受け取ることさえありません。以下は、リクエストを行うために使用しているコードです。

ログインします:

private static CookieContainer PerformLoginRequest()
{
    string loginURL = "http://www.myDomain.com/mySite/login.aspx";

    //Set up the request and give it a cookie container.
    CookieContainer cookieJar = new CookieContainer();
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(loginURL);
    request.CookieContainer = cookieJar;
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";

    //Grab the request body so we can put important information in it.
    Stream requestBody = request.GetRequestStream();
    string postData = "__VIEWSTATE=GIBBERISH&UserName=USERNAME&Password=PASSWORD%21&LoginButton.x=0&LoginButton.y=0";

    //Throw the string into the body.
    ASCIIEncoding encoding = new ASCIIEncoding();
    byte[] byte1 = encoding.GetBytes(postData);
    requestBody.Write(byte1, 0, byte1.Length);
    requestBody.Close();

    //Get the response to the login request.
    WebResponse response = request.GetResponse();
    StreamReader reader = new StreamReader(response.GetResponseStream());
    string result = reader.ReadToEnd();
    reader.Close();

    return cookieJar;
}

ページをリクエストするには:

private static long RequestPage(string url)
{
    //If we've already got a CookieContainer, then we've logged in already. Otherwise, log in.
    if (cookieJar == null)
    {
        try
        {
            cookieJar = PerformLoginRequest();
        }
        catch
        {
            throw;
        }
    }

    //Set up the request.
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
    request.CookieContainer = cookieJar;
    request.Method = "GET";
    request.ContentType = "application/x-www-form-urlencoded";
    request.Timeout = timeout; //5 minutes.

    WebResponse response = request.GetResponse();

    return response.ContentLength;
}

cookieJar およびタイムアウト変数は、アプリケーションに対してグローバルです。

何が原因でしょうか?

更新 (2010 年 1 月 17 日午後 3 時 30 分 EST)

Fiddler を実行してアプリケーションを起動すると、すべてがうまくいきます。期待どおり、すべてのリクエストが機能します。

IIS ログ ファイルを調べました。それらの中で、最初のログイン リクエスト、ログイン後のリダイレクト、および最初の 2 ページのリクエストを確認できます。しかし、その後...何もありません。リクエストがWebサーバーに届かないようです。

更新 (2010 年 1 月 18 日午前 11 時 29 分 EST)

Chris B. Behrens によって提案された変更を反映するために、コードを更新しました。しかし、役に立たない。重要な場合、上記の関数を呼び出すループは次のようになります。

private static void RegenerateNecessaryForms(MyEntities context)
{
    var items = context.Items.Where(i => i.NeedsProcessing == true);

    var area = context.Areas;
    foreach (Item i in items)
    {
        bool success = true;
        foreach (Area area in areas)
        {
            try
            {
                string url = string.Format("http://{0}/mySite/process.aspx?item={1}&area={2}", targetDomain, i.ItemName, area.AreaName);
                long result = RequestPage(url, m);
            }
            catch
            {
                success = false;
            }
        }

        if (success)
        {
            i.NeedsProcessing = false;
        }
    }
}

更新 (2010 年 1 月 18 日、東部標準時午後 1 時 3 分) これはおそらく、これまでに提供できた中で最も有用な情報です。

IIS ログをもう一度見ていました。ログイン要求が送信されたら、ログをフラッシュするとすぐに表示されます。ただし、コンソール アプリケーションを閉じるまで、ページ リクエストは表示されません。ログの関連するビットは次のとおりです。

2011-01-18 17:44:54 X.X.X.X POST /MySite/login.aspx - 80 - X.X.X.X - 302 0 0 148
2011-01-18 17:44:54 X.X.X.X GET /MySite/default.aspx - 80 AutomatedUser X.X.X.X - 200 0 0 48
2011-01-18 17:54:33 X.X.X.X GET /MySite/process.aspx model=ITEM_ONE&area=US 80 AutomatedUser X.X.X.X - 200 0 995 579100
2011-01-18 17:54:33 X.X.X.X GET /MySite/process.aspx model=ITEM_ONE&area=CANADA 80 AutomatedUser X.X.X.X - 200 0 995 553247
2011-01-18 17:54:33 X.X.X.X GET /MySite/process.aspx model=ITEM_TWO&area=US 80 AutomatedUser X.X.X.X - 200 0 995 532824

process.aspx に対する各 GET 要求は、上記の RequestPage メソッドの呼び出しに対応しています。「request.GetResponse();」という行 約 10 秒ほどしかかかりませんが、アプリケーションを閉じるまで、(少なくとも IIS によると) リクエストが完了しないように見えます。(各行の最後の数字を見ると、それはミリ秒単位でページを提供するのにかかった時間ですが、私はそれよりもはるかに短い時間でアプリケーションに応答を返しました。) ) IIS が 1 つの IP から受け入れる接続の量を制限していること。

これは私に質問をもたらします: 私が行っている要求について、それらがそのように「オープン」のままになる原因は何ですか?

リクエストは HTML ページを返さず (問題がある場合)、PDF を返します。

4

1 に答える 1

0

リクエストを明示的に閉じていません:

//Get the response to the login request.
WebResponse response = request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string result = reader.ReadToEnd();

reader.Close();

return cookieJar;

それがうまくいくかどうか見てください。

于 2011-01-18T15:10:57.500 に答える