2012-05-12 18 views
1

我想爲Windows Phone 7芒果做一個應用程序來解析網站的內容。我設法編寫所有的代碼,但它就像一個戰區;)。當我嘗試以更好的方式重新排列代碼時,我開始面臨一個非常奇怪的問題。HttpWebRequest裏面的自定義類

問題是,當我在我的項目中創建一個名爲「MedinetMySchedule」的自定義類並使用斷點來逐步完成此類時。我發現應用程序逐步執行第一個方法getrequest(),然後返回主頁面幾步,然後返回到第二個方法GetRequestStreamCallback()。這跳轉到主頁留給我一個字符串值爲null解析。然後它跳回到第三個方法ReadWebRequestCallback()。最後一次跳轉給我沒有什麼重要的,因爲調試結束了,我在電話模擬器上什麼也沒有得到。該MedinetMySchedule類具有下面的代碼: -

namespace WindowsPhonePanoramaApplication1 
{ 
    public class MedinetMySchedule 
    { 

     //Medinet user url 
     public string url { get; set; } 
     public String myresponse; 
     public void getrequest() 
     { 
      HttpWebRequest request = HttpWebRequest.CreateHttp(url); 
      request.Method = "POST"; 
      request.ContentType = "application/x-www-form-urlencoded"; 
      request.BeginGetRequestStream(GetRequestStreamCallback, request); 
     } 

     private void GetRequestStreamCallback(IAsyncResult asynchronousResult) 
     { 
      HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; 
      using (Stream postStream = request.EndGetRequestStream(asynchronousResult)) 
      { 
       string postData = string.Format("username={0}&password={1}&customer=******&doLogin=Logga+in&language=se", "*****", "******"); 

       // Convert the string into a byte array. 
       byte[] data = Encoding.UTF8.GetBytes(postData); 


       // Write to the request stream. 
       postStream.Write(data, 0, data.Length); 
       postStream.Close(); 
      } 

      //Initiating get response 
      request.BeginGetResponse(ReadWebRequestCallBack, request); 

     } 

     private void ReadWebRequestCallBack(IAsyncResult asynchronousResult) 
     { 
      HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; 
      WebResponse myResponse = (WebResponse)request.EndGetResponse(asynchronousResult); 
       Stream encodingStream = myResponse.GetResponseStream(); 
       Encoding encode = Encoding.GetEncoding("iso-8859-1"); 
       using (StreamReader httpwebStreamReader = new StreamReader(encodingStream, encode)) 
       { 
        myresponse= httpwebStreamReader.ReadToEnd(); 
       } 
       myResponse.Close(); 
     } 
    } 
} 

這裏是調用的GetRequest(代碼),並解析內容: -

  MedinetMySchedule mittschema = new MedinetMySchedule(); 
     mittschema.url = "https://medinet.se/cgi-bin/doctor.pl?action=login&customer=saskir&language=se"; 
     mittschema.getrequest(); 
     Dispatcher.BeginInvoke(() => parseResults(mittschema.myresponse)); 
     private void parseResults(string myresponse) 
    { 
     if (string.IsNullOrEmpty(myresponse)) 
     { 
      return; 
     } 

     //Initiating a listbox and add item to it 
     List<MediNetScheme> medinetScheme = new List<MediNetScheme>(); 
     //Using HtmlAgilityPack to parse the HTMLcode from the response 
     HtmlDocument htdoc = new HtmlDocument(); 
     htdoc.LoadHtml(myresponse); 
     foreach (HtmlNode table in htdoc.DocumentNode.SelectNodes("//table[@class='list-medium']/tbody[1]/tr[@class]")) 
     { 
      //Removing ChildNode 
      table.ChildNodes.RemoveAt(3); 
      string itemValue = table.InnerText; 
      //Changing the parsed date into a DateTime 
      string d; 
      DateTime datum = DateTime.Parse(itemValue.Remove(11)); 
      d = datum.ToString("D"); 
      //Adding items to the listbox 
      medinetScheme.Add(new MediNetScheme() { Datum = d, Sections = itemValue.Remove(0, 15) }); 
     } 
     MediNetScheme.ItemsSource = medinetScheme; 

    } 

任何想法,爲什麼發生這種情況以及如何糾正它?

此致 /奧馬爾

回答

2

執行來回是因爲request.BeginGetRequestStream是異步的。基本上,它會創建一個新線程,並與主代碼並行執行。因此,在完成下載數據之前,最終調用parseResult。有許多方法來重寫你的代碼中,我最喜歡的是使用一個回調:

首先,更改調用getRequest方法接受一個回調,並將其存儲:,

private Action Callback; 

    public void getrequest(Action callback) 
    { 
     this.Callback = callback; 
     HttpWebRequest request = HttpWebRequest.CreateHttp(url); 
     request.Method = "POST"; 
     request.ContentType = "application/x-www-form-urlencoded"; 
     request.BeginGetRequestStream(GetRequestStreamCallback, request); 
    } 

然後在ReadWebRequestCallback結束,調用這個回調:

private void ReadWebRequestCallBack(IAsyncResult asynchronousResult) 
    { 
     HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; 
     WebResponse myResponse = (WebResponse)request.EndGetResponse(asynchronousResult); 
      Stream encodingStream = myResponse.GetResponseStream(); 
      Encoding encode = Encoding.GetEncoding("iso-8859-1"); 
      using (StreamReader httpwebStreamReader = new StreamReader(encodingStream, encode)) 
      { 
       myresponse= httpwebStreamReader.ReadToEnd(); 
      } 
      myResponse.Close(); 

     this.Callback(); 
    } 

最後,從炫魅,調用的GetRequest方法,並告訴它使用parseResults回調:

Action callback =() => Dispatcher.BeginInvoke(() => parseResults(mittschema.myresponse)); 
mittschema.getrequest(callback); 
+0

我的天啊!你只是保存我的一天,或者我應該說我的夜晚;)。非常感謝你的努力和時間。它的作用就像學習的魅力和學習。 – DreamNet