Не работает экранная страница ASP.NET - PullRequest
0 голосов
/ 04 августа 2011

Я пытаюсь вернуть события календаря на странице на следующем сайте: http://www.wphospital.org/News-Events/Calendar-of-Events.aspx

Обратите внимание, что на этом сайте есть ссылка "Месяц" - мне нужно иметь возможность отправлять данные POST, запрашивая календарьсобытия за определенный месяц.Я не могу заставить это работать.Вот код:

private static void GetData(ref string buf)
{
    try
    {
        //First, request the search form to get the viewstate value 
        HttpWebRequest webRequest = default(HttpWebRequest);
        webRequest = (HttpWebRequest)System.Net.WebRequest.Create("http://www.wphospital.org/News-Events/Calendar-of-Events.aspx");
        StreamReader responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream());
        string responseData = responseReader.ReadToEnd();
        responseReader.Close();

        //Extract the viewstate value and build out POST data 
        string viewState = ExtractViewState(responseData);
        string eventValidation = ExtractEventValidation(responseData);
        string postData = null;

        postData = String.Format("ctl00$manScript={0}&__EVENTTARGET=&__EVENTARGUMENT&__LASTFOCUS=&__VIEWSTATE={1}&lng={2}&__EVENTVALIDATION={3}&ctl00$searchbox1$txtWord={4}&textfield2={5}&ctl00$plcMain$lstbxCategory={6}&ctl00$plcMain$lstbxSubCategory={7}", "ctl00$plcMain$updMonthNav|ctl00$plcMain$btnNextMonth", viewState, "en-US", eventValidation, "Search", "your search here", 0, 0);

        var encoding = new ASCIIEncoding();
        byte[] data = encoding.GetBytes(postData);

        //Now post to the search form 
        webRequest = (HttpWebRequest)System.Net.WebRequest.Create("http://www.wphospital.org/News-Events/Calendar-of-Events.aspx");
        webRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)";
        webRequest.Method = "POST";
        webRequest.ContentType = "application/x-www-form-urlencoded";
        webRequest.ContentLength = data.Length;

        var newStream = webRequest.GetRequestStream();
        newStream.Write(data, 0, data.Length);
        newStream.Close();

        responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream());

        //And read the response 
        responseData = responseReader.ReadToEnd();
        responseReader.Close();
        buf = responseData;
    }
    catch (WebException ex)
    {
        if (ex.Status == WebExceptionStatus.ProtocolError)
        {
            Console.Write("The server returned protocol error ");
            // Get HttpWebResponse so that you can check the HTTP status code.
            HttpWebResponse httpResponse = (HttpWebResponse)ex.Response;
            int sc = (int)httpResponse.StatusCode;
            string strsc = httpResponse.StatusCode.ToString();
        }
    }
}

private static string ExtractViewState(string s)
{
    string viewStateNameDelimiter = "__VIEWSTATE";
    string valueDelimiter = "value=\"";

    int viewStateNamePosition = s.IndexOf(viewStateNameDelimiter);
    int viewStateValuePosition = s.IndexOf(valueDelimiter, viewStateNamePosition);

    int viewStateStartPosition = viewStateValuePosition + valueDelimiter.Length;
    int viewStateEndPosition = s.IndexOf("\"", viewStateStartPosition);

    return HttpUtility.UrlEncodeUnicode(s.Substring(viewStateStartPosition, viewStateEndPosition - viewStateStartPosition));
}

Кто-нибудь может указать мне правильное направление?

Ответы [ 3 ]

1 голос
/ 05 августа 2011

Это может решить, а может и не решить вашу проблему, потому что я точно не знаю, в чем проблема, когда вы говорите, что она не работает.Но, как заметил «Al W», ответ от асинхронной обратной передачи не будет выглядеть как прямой поток HTML.Так что, если ваша проблема в последующем анализе, тогда это может помочь.

У меня была «возможность» обнаружить это недавно, потому что мне нужно было переписать этот вывод.Я работаю над C # jQuery портом и обнаружил, что я ломал страницы WebForms, когда пытался повторно визуализировать поток вывода во время асинхронной обратной передачи.Я прошел через клиентский скрипт, который анализирует ответ и выяснил формат ответа.

Каждая обновленная панель будет возвращать блок данных, отформатированный как:

"Длина | Тип | ID | Содержимое"

Может быть любое количество этихсвязаны вместе.Тип "updatePanel" для UpdatePanels.ID - это уникальный идентификатор элемента управления, а содержимое - это фактические данные HTML.Длина равна количеству байтов в содержимом, и вам нужно использовать это для разбора каждого блока, потому что символ разделителя может появиться внутри самого содержимого.Поэтому, если вы решили, что хотите переписать эти данные перед отправкой их обратно на страницу ASP.NET (как я это сделал), вам нужно обновить Length, чтобы отразить окончательную длину вашего контента.

Код, который я использовал дляразобрать и переписать это в Server / CsQueryHttpContext .

0 голосов
/ 05 августа 2011

Ниже приведена трассировка сети, которую я получаю в chrome при нажатии кнопки ежемесячно.Обратите внимание, что __EVENTTARGET: ctl00 $ plcMain $ monthBtn asp.net имеет инфраструктуру javascript, которая вызывает метод javascript: postback () при нажатии на эту ссылку, которая устанавливает цель события.Это в основном то, как веб-формы ASP.NET знают, какое событие вызывать при обратной передаче.Одна хитрость здесь в том, что веб-страница использует панель обновления, поэтому вы можете не получить истинный ответ HTML.Если вы можете получить ваш запрос, чтобы выглядеть примерно так, то вы должны получить успешный ответ.Надеюсь, это поможет.

Request URL:http://www.wphospital.org/News-Events/Calendar-of-Events.aspx
Request Method:POST
Status Code:200 OK
Request Headers
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Content-Length:9718
Content-Type:application/x-www-form-urlencoded
Cookie:CMSPreferredCulture=en-US; ASP.NET_SessionId=h2nval45vq0q5yb0cp233huc; __utma=101137351.234148951.1312486481.1312486481.1312486481.1; __utmb=101137351.1.10.1312486481; __utmc=101137351; __utmz=101137351.1312486481.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __unam=ef169fe-131964a5f2a-24ec879b-1
Host:www.wphospital.org
Origin:http://www.wphospital.org
Proxy-Connection:keep-alive
Referer:http://www.wphospital.org/News-Events/Calendar-of-Events.aspx
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.124 Safari/534.30
X-MicrosoftAjax:Delta=true
Form Dataview URL encoded
ctl00$manScript:ctl00$plcMain$updTab|ctl00$plcMain$monthBtn
__EVENTTARGET:ctl00$plcMain$monthBtn
__EVENTARGUMENT:
__LASTFOCUS:
__VIEWSTATE:<removed for brevity>
lng:en-US
__EVENTVALIDATION:/wEWEgLbj/nSDgKt983zDgKWlOLbAQKr3LqFAwKL3uqpBwK9kfRnArDHltMCAuTk0eAHAsfniK0DAteIosMPAsiIosMPAsmIosMPAsuIosMPAoD0ookDApCbiOcPAo biOcPAombiOcPAoubiOcPyfqRx8FdqYzlnnkXcJEJZzzopJY=
ctl00$searchbox1$txtWord:Search
textfield2:Enter your search here
ctl00$plcMain$lstbxCategory:0
ctl00$plcMain$lstbxSubCategory:0
ctl00$plcMain$hdnEventCount:2
0 голосов
/ 04 августа 2011

Для операций POST вы хотите, чтобы он был в кодировке UTF-8, поэтому просто повторите одну строку

        //var encoding = new ASCIIEncoding();
        //byte[] data = encoding.GetBytes(postData);
        //do this instead.....
        byte[] data = Encoding.UTF8.GetBytes(postData);

и посмотрите, поможет ли это вам

...