1. 程式人生 > >HttpWebRequest開發向asp.net服務端post資料,對ViewState的處理

HttpWebRequest開發向asp.net服務端post資料,對ViewState的處理

當Windows Mobile程式需要使用Web Server的資訊,一開始自然會想到使用WebService。可是有些Web Server不提供WebService,只是提供Http瀏覽功能,如果需要從Http網頁中得到資訊,可以使用HttpWebRequest和HttpWebResponse來完成,下面通過一個例子來講述。
 例如有一個使用ASP.net開發的燃料價格查詢網站。


 圖1

 輸入燃料型別(Fuel Type)和郵政編碼(Postcode)後可以查詢出燃料價格,如下圖。


 圖2

 在Windows Mobile下需要開發一個應用程式,輸入燃料型別和郵編,然後通過通過Web Server查詢出價格資訊,顯示到Windows Mobile裡面。由於該Web Server不提供WebService的服務,所以該Windows Mobile程式不能直接通過Webservice取出價格資訊,可以通過HttpWebRequest來實現。關於HtppWebRequest可以參考下面兩篇不錯的文章。

 使用HttpWebRequest提交ASP.NET表單並保持Session和Cookie

  HttpWebRequest/Response in a nutshell - Part 1
 總體開發分幾步:第一步找出需要提交的資料;第二步訪問該頁面,取出ViewState;第三步組成Post的資料併發送請求;第四步分析HTML並顯示結果。

點此發表你的看法>>【已有位網友發表了看法】
 找出需要提交的資料

 找出需要提交的資料最常用的工具是HttpWatch,可是這個工具免費的basic版本只是支援google,microsoft等網站,所以我使用了一個Firefox免費外掛HttpFox,事實證明該工具滿足我的需求。

 先安裝HttpFox,然後點選HttpFox的"Start"啟動。開啟要提交的頁面,例子為 http://localhost/HttpWebRequest/Default.aspx,點選頁面中的"Search"按鈕。檢視HttpFox的"Post Data"Tab頁,能找出所有需要提交的資料,如下圖

 需要提交的POST包括__VIEWSTATE, __EVENTVALIDATION, DropDownListFuelType, TextBoxPostCode以及 ButtonSearchPostcode


 圖3

點此發表你的看法>>【已有位網友發表了看法】
 取出ViewState

 進行ASP.net的webform開發,關鍵是瞭解頁面的生命週期,其中一個關鍵點是ViewState,後臺把所需要的資訊存放到一個叫做__VIEWSTATE的隱藏input框裡,這__VIEWSTATE會往伺服器回傳服務端控制元件資訊(Server controls),下面就是一個ViewState的例子。

  <div>

 <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTE5NjAwMTc3OTQPZBYCAgMPZBYCAgEPDxYCHgRUZXh0BTRDbGljazogRnVlbD1bRGllc2VsXSwgUG9zdGNvZGVyPVsyMDE0XSwgUHJpY2VzPVsxLjVdZGRkPwaT5ufoa4sSWz2jkkc4+1mjzgA=" />

 </div>

 <div>

 <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWCALvtKiPBwLHjuPuBALEjuPuBALFjuPuBALCjuPuBALDjuPuBAKJr8zPBQLj1NuXC4Mp8caGaDkuTJ50BTH0riQ7xWbK" />

 </div>
 在CF.NET下進行HttpWebRequest開發,如果服務端是ASP.net的程式,需要處理ViewState。從圖3上看,除了__VIEWSTATE還需要處理__EVENTVALIDATION,其實很簡單,通過HttpFox看那個需要取那個。

  //Get the ViewState and EventValidation

 HttpWebRequest request = WebRequest.Create(URI) as HttpWebRequest;

 request.Method = "GET";

 request.KeepAlive = false;

 //Get the response

 HttpWebResponse response = request.GetResponse() as HttpWebResponse;

 System.IO.Stream responseStream = response.GetResponseStream();

 System.IO.StreamReader reader = new System.IO.StreamReader(responseStream, Encoding.UTF8);

 string srcString = reader.ReadToEnd();

 //Get the ViewState

 string viewStateFlag = "id=/"__VIEWSTATE/" value=/"";

 int i = srcString.IndexOf(viewStateFlag) + viewStateFlag.Length;

 int j = srcString.IndexOf("/"", i);

 string viewState = srcString.Substring(i, j - i);

 //Get the ViewState

 string EventValidationFlag = "id=/"__EVENTVALIDATION/" value=/"";

 i = srcString.IndexOf(EventValidationFlag) + EventValidationFlag.Length;

 j = srcString.IndexOf("/"", i);

 string eventValidation = srcString.Substring(i, j - i);
 取ViewState要先訪問提交前的網頁,使用HttpWebRequest request = WebRequest.Create(URI) as HttpWebRequest;生成一個HttpWebRequest的物件,引數為Web伺服器的地址,提交方式為"GET",其實這個方式也可以通過HttpFox看到的,如下圖:


 圖4

 先啟動HttpFox,然後輸入網址,看第一行知道這是一個"GET"操作。

 HttpWebResponse response = request.GetResponse() as HttpWebResponse;為向Web伺服器傳送請求,並得到返回資訊。返回的資訊其實就是圖4裡的"Content"Tab頁,也就是HTML資訊,裡面包含我們需要的ViewState。

 組成Post的資料併發送請求

 處理結果得到__VIEWSTATE和__EVENTVALIDATION,然後可以組成提交操作還需要組成Post的資料,如下程式碼

  //Compose the URL

 viewState = Uri.EscapeDataString(viewState);

 eventValidation = Uri.EscapeDataString(eventValidation);

 string formatString = "__VIEWSTATE={0}&__EVENTVALIDATION={1}&DropDownListFuelType={2}&TextBoxPostCode={3}&ButtonSearchPostcode=Search";

 string postString = string.Format(formatString, viewState, eventValidation, fuelType, postCode);

 //Change to byte[]

 byte[] postData = Encoding.ASCII.GetBytes(postString);

 //Compose the new request

 request = WebRequest.Create(URI) as HttpWebRequest;

 request.Method = "POST";

 request.KeepAlive = false;

 request.ContentType = "application/x-www-form-urlencoded";

 request.ContentLength = postData.Length;

 System.IO.Stream outputStream = request.GetRequestStream();

 outputStream.Write(postData, 0, postData.Length);

 outputStream.Close();

 //Get the new response

 response = request.GetResponse() as HttpWebResponse;

 responseStream = response.GetResponseStream();

 reader = new System.IO.StreamReader(responseStream);

 srcString = reader.ReadToEnd();

 return srcString;
點此發表你的看法>>【已有位網友發表了看法】
 Post的資料需要使用Uri.EscapeDataString格式化,如果提交的資料包含中文,一定要進行這一步操作,否則會出錯。

 string formatString = "__VIEWSTATE={0}&__EVENTVALIDATION={1}&DropDownListFuelType={2}&TextBoxPostCode={3}&ButtonSearchPostcode=Search";

  string postString = string.Format(formatString, viewState, eventValidation, fuelType, postCode);
 就是組成Post的記憶體,所有內容來自於HttpFox的分析,見圖3,需要什麼組成什麼。

 然後再使用HttpWebRequest和HttpWebResponse提交,得到返回結果,這個結果包含了我們需要的價格資訊。

 分析HTML並顯示結果

 得到結果後,需要分析HTML並把我們需要的資訊顯示出來,在這一例子裡,使用簡單的字串分析,從LabelResult裡得到價格資訊。

 int i = srcString.IndexOf("Price=[");

 int j = srcString.IndexOf("</span>");

 labelPrice.Text = srcString.Substring(i, j - i);
 這裡只是一個簡單的例子,在實際運用中可以使用正則表達來分析,或者使用HTML分析器來解釋。

 到目前為止已經講述了一個簡單的HttpWebRequest運用。原始碼見下面。執行該程式碼,需要修改IP地址,這裡hardcode了Server的地址。