【问题标题】:HttpWebRequest inside a custom class自定义类中的 HttpWebRequest
【发布时间】:2012-05-12 23:08:15
【问题描述】:

我正在尝试为 windows phone 7 mango 制作一个应用程序,以解析网站的内容。我设法编写了所有代码,但它就像一个战区;)。当我试图以更好的方式重新排列代码时,我开始面临一个非常奇怪的问题。

问题是当我在我的项目中创建了一个名为“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;

    }

任何想法为什么会发生这种情况以及如何纠正它?

你的 /奥马尔

【问题讨论】:

    标签: windows-phone-7 c#-4.0 httpwebrequest


    【解决方案1】:

    来回执行是因为 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);
    

    【讨论】:

    • 天哪!你只是拯救了我的一天,或者我应该说我的夜晚;)。非常感谢您的努力和时间。它就像魅力和经验教训一样起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-21
    • 2012-04-08
    • 1970-01-01
    • 2016-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多