【IT168技術】上周完成了一個從ASP.NET WebForm 開發的站點抓包的功能。該功能要求使用該網點內的帳號通過我們自己的程序獲取網站內的數據。其間使用了HttpWebRequest 進行抓包。具體的抓包過程就不重點討論了。旨在和大家分享一下我在抓包過程中對ViewState 在 ASP.NET WebForm 中的作用有了進一步的了解。如果存在不足之處,希望您能指出。
為了模擬Http POST/GET 我們用VS建立兩個工程,截圖如下:
注:第一個工程是一個簡單的ASP.NET Web Form 程序,第二個是模擬Web Form 的 WinForm 程序。
WebApplication1 執行如下:
兩個伺服器端控制項 DropDownList 和 Button 伺服器端相應事件如下:
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
if (DropDownList1.SelectedValue == "Two")
{
lblInfor.Text = "Two";
}
else
{
lblInfor.Text = "One";
}
}
功能代碼非常簡單,Button1被單擊後顯示dropdownlist 的文本值:
Webform介紹完,剩下就是用WinForm 通過HTTP POST/GET來模擬Web Form 程序,程序運行界面如下:
這裡的OnePost 與TwoPost 分別模擬WebForm中 Post 按鈕Click功能。
貼出模擬的核心代碼:PostByWebRequest 函數:
1 private void PostByWebRequest(string strPostValue)
2 {
3 try
4 {
5 string URI = "http://localhost:2026/webform1.aspx/";
6 HttpWebRequest request = WebRequest.Create(URI) as HttpWebRequest;
7 request.Method = "GET";
8 request.KeepAlive = true;
9 request.CookieContainer = cookieContainer;
10 HttpWebResponse response = request.GetResponse() as HttpWebResponse;
11 System.IO.Stream responseStream = response.GetResponseStream();
12 System.IO.StreamReader reader = new System.IO.StreamReader(responseStream, Encoding.UTF8);
13 //返回的頁面html文本
14 string srcString = reader.ReadToEnd();
15 //VeiwState
16 string viewStateFlag = "id=\"__VIEWSTATE\" value=\"";
17 int len1 = srcString.IndexOf(viewStateFlag) + viewStateFlag.Length;
18 int len2 = srcString.IndexOf("\"", len1);
19 string viewState = srcString.Substring(len1, len2 - len1);
20 //EventValidation
21 string eventValidationFlag = "id=\"__EVENTVALIDATION\" value=\"";
22 len1 = srcString.IndexOf(eventValidationFlag) + eventValidationFlag.Length;
23 len2 = srcString.IndexOf("\"", len1);
24 string eventValidation = srcString.Substring(len1, len2 - len1);
25
26 //編碼
27 viewState = System.Web.HttpUtility.UrlEncode(viewState);
28 eventValidation = System.Web.HttpUtility.UrlEncode(eventValidation);
29
30 //這裡可以通過抓包工具獲得poststring.記得中文需要UrlEncode編碼。
31 string formatString = "DropDownList1={0}&Button1={1}&__VIEWSTATE={2}&__EVENTVALIDATION={3}";
32 string postString = string.Format(formatString, strPostValue,
33 "Do PostBack", viewState, eventValidation);
34
35 byte[] postData = Encoding.UTF8.GetBytes(postString);
36
37 URI = "http://localhost:2026/webform1.aspx/";
38 //POST
39 request = WebRequest.Create(URI) as HttpWebRequest;
40 request.Method = "POST";
41 request.KeepAlive = false;
42 request.ContentType = "application/x-www-form-urlencoded";
43 request.CookieContainer = cookieContainer;
44 request.ContentLength = postData.Length;
45
46 System.IO.Stream outputStream = request.GetRequestStream();
47 outputStream.Write(postData, 0, postData.Length);
48 outputStream.Close();
49
50 response = request.GetResponse() as HttpWebResponse;
51 responseStream = response.GetResponseStream();
52 reader = new System.IO.StreamReader(responseStream, Encoding.UTF8);
53 srcString = reader.ReadToEnd();
54 }
55 catch (Exception ex)
56 {
57 string msg = ex.Message;
58 MessageBox.Show(ex.Message);
59 }
60 }
PostByWebRequest函數調用如下:
OnePost 按鈕單擊執行: PostByWebRequest("One");
TwoPost 按鈕單擊執行: PostByWebRequest("Two");
註:如果在PostByWebRequest函數的第31行,不傳入ViewState或EVENTVALIDATION,WinForm內的兩個按鈕均不能成功模擬WebForm。最終模擬的正確效果是:預先在WebForm 的 Button_Click內設置斷點,接著點擊WinForm內的兩個按鈕,VS會自動截獲到該斷點設置。說明我們順利模擬了WebForm的POST的機制。如果點擊TwoPost 按鈕時,WebForm 伺服器端不但會執行Post按鈕事件還會執行DropDownlist 的SelectedIndexChanged事件。為什麼會執行到DropDownlist 的SelectedIndexChanged事件呢?這一切都歸功於ViewState。它記錄了WebForm的表單內容從而做出了相應的處理。所以WebForm 的 ViewState 機制還是很強大的。讓我們用事件機制去開發Web程序。同時ViewState機制讓我們的web form 程序更難被「爬蟲」獲取程序內容,想用程序Post WebForm 就必須傳入傳入ViewState 。否則POST不會返回正確的頁面內容。
原文地址:http://www.cnblogs.com/ryanding/archive/2011/01/17/1936392.html