为了它的价值,我设法获得了一个控制台应用程序,以使用现有的ASP.NET Web应用程序对自身进行身份验证。它只是通过向包含视图状态信息的登录页面发出发布请求来模仿登录页面(就像浏览器发出了请求一样)。
然后它会捕获在CookieContainer中发回的cookie。
然后,应用程序继续向同一页面发出多个请求(需要授权)。该页面可以正常工作并在服务器上写出文件。
我遇到的问题是,在虚假登录后,前两个请求通过正常。第三个请求甚至从未收到回复。下面是我用来发出请求的代码:
登录:
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-01-17,美国东部时间下午3:30)
当我使用Fiddler运行启动应用程序时,一切都很顺利。正如我所料,所有请求都起作用。
我检查了IIS日志文件。在其中我可以看到初始登录请求,登录后的重定向以及前两页的请求。但在那之后......什么都没有。这就像请求甚至没有进入Web服务器。
更新(2010-01-18,美国东部时间上午11:29)
我更新了代码,以反映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-01-18,美国东部时间下午1:03) 这可能是迄今为止我能够提供的最有用的信息。
我再次查看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正在限制它将从一个IP接受的连接数量。
这让我想到了一个问题:我正在制作的请求是什么导致他们保持“开放”状态?
请求不会返回HTML页面(如果这很重要),它们会返回PDF。
答案 0 :(得分: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;
看看是否有诀窍。