С# экран соскабливает страницу веб-форм ASP.NET - запрос POST не полностью работает

Пожалуйста, несите меня за это слегка длинное описание, но у меня возникла странная проблема с отображением С# на странице веб-форм ASP.NET. Шаги, которые я пытаюсь сделать, следующие: -

1) Сайт защищен с использованием базовой проверки подлинности по протоколу HTTPS, поэтому мне необходимо войти в систему соответствующим образом.

2) Я выполняю запрос GET на странице, чтобы получить значение __VIEWSTATE (чертово ничего не делает, если я не устанавливаю эту вещь!)

3) После входа в систему есть несколько полей формы для заполнения, затем кнопка отправки, которая отправляет форму на сервер

4) Когда кнопка отправки нажата, форма отправляется на сервер, а ответ представляет собой одну и ту же страницу и форму, но теперь с небольшой таблицей HTML в нижней части формы с некоторыми данными, которые мне нужно получить.

Мне до сих пор удалось отсортировать сообщение для входа и формы, используя класс WebClient. Я использовал fiddler (и firebug), чтобы проверить значения поля POST, которые отправляются при заполнении формы, обычно используя браузер. Я могу успешно получить ответ от запроса POST с соответствующей таблицей данных, отображаемой ниже формы, как и ожидалось. Однако проблема заключается в том, что, хотя в таблице заполнены данные, она заполнена данными, которых я не ожидаю. Появившиеся данные, если я заполнил форму в браузере как обычно, но с одним конкретным параметром (выпадающим списком), установленным на другое значение, чем я передаю свой запрос POST на сервер. Я подтвердил использование fiddler и firebug, что я передаю точно те же параметры POST, которые отправляются как обычно с использованием заполненной формы веб-браузера. Я теперь полностью зациклился на том, почему этот параметр не "принимается во внимание" сервером?

Единственное отличие состоит в том, что этот конкретный элемент управления является списком выбора, и при изменении он выполняет перезагрузку страницы или "обратную передачу". Однако это, похоже, не делает ничего, кроме изменения какого-либо другого содержимого списков списков позже в форме.

Наверное, я спрашиваю, есть ли что-то еще, что мне не хватает, что может вызвать это? Я полностью разорвал свои волосы на этом. Может ли кто-нибудь помочь? Я разместил код ниже (с адресами и параметрами, скрытыми для конфиденциальности).

    // a place to store the html
    string responseBody = "";

    // create out web client to handle the request
    using (WebClient webClient = new WebClient())
    {
        // space to store responses from the remote site
        byte[] responseBytes;

        // site uses basic authentication over HTTPS so we'll need to login
        CredentialCache credentials = new CredentialCache();
        credentials.Add(new Uri(Url), "Basic", new NetworkCredential(Username, Password));

        // set the credentials in the web client
        webClient.Credentials = credentials;

        // a place for __VIEWSTATE
        string viewState = "";

        // try and get __VIEWSTATE from the web site
        try
        {
            responseBytes = webClient.DownloadData(Url);
            viewState = GetHtmlInputValue(Encoding.UTF8.GetString(responseBytes), "__VIEWSTATE");
        }
        catch (Exception e)
        {
            bool cancel = false;
            ComponentMetaData.FireError(10, "Read web page data", "Error whilst trying to get __VIEWSTATE from web page: " + e.Message, "", 0, out cancel);
        }

        // add our POST parameters (don't forget the __VIEWSTATE or it won't work as its an ASP.NET web page)
        NameValueCollection requestParameters = new NameValueCollection();

        // add ASP.NET fields
        requestParameters.Add("__EVENTTARGET", __EVENTTARGET);
        requestParameters.Add("__EVENTARGUMENT", __EVENTARGUMENT);
        requestParameters.Add("__LASTFOCUS", __LASTFOCUS);

        // add __VIEWSTATE
        requestParameters.Add("__VIEWSTATE", viewState);

        // all other form parameters
        requestParameters.Add("btnSubmit", btnSubmit);      
        /* I've hidden the rest of the parameters hidden for privacy just in case */

        // see if we can connect and get data
        try
        {
            // set content type
            webClient.Headers.Clear();
            webClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded");                             

            // 'POST' the form data using web client and hope we get a response
            responseBytes = webClient.UploadValues(Url, "POST", requestParameters);

            // transform the response to a string
            responseBody = Encoding.UTF8.GetString(responseBytes);
        }
        catch (Exception e)
        {
            bool cancel = false;
            ComponentMetaData.FireError(10, "Read web page data", "Error whilst trying to connect to web page: " + e.Message, "", 0, out cancel);
        }
    }

Пожалуйста, игнорируйте ссылки "ComponentMetaData", поскольку это часть источника SSIS script.

Любые идеи или помощь будут очень благодарны - приветствия!

RE: спасибо за быстрые ответы, все, что я могу сказать этим комментариям...

Там обычный cookie сеанса ASP, но в cookie нет значений (кроме конечно идентификатора сеанса), я понял, что сайт использует базовую аутентификацию, а не проверку подлинности. Я мог просто игнорировать файл cookie - и, поскольку я попав на сайт и получив данные, все было в порядке. Я думаю, это стоит попробовать, но мне придется просто изменить код, чтобы вместо этого использовать метод класса WebRequest...

Что касается javascript списка выбора, нет никакого javascript, изменяющего значение списка выбора после загрузки страницы. Единственный javascript в списке выбора - это событие onchange, чтобы сделать "postback", который, по-видимому, изменяет некоторые другие списки выбора в форме, которая в любом случае является пустой в окончательной POST. Примечание. Я включаю все параметры POST при генерации запроса POST, даже если они пусты, и я также включаю все специальные поля "веб-форм", такие как __VIEWSTATE, __EVENTTARGET и т.д.

Я не эксперт в веб-формах (сам MVC сам), но есть ли что-нибудь еще, что ожидает "движок" веб-форм? Я отправил 1 заголовок для "Content-Type" для "application/x-www-form-urlencoded", но я попытался настроить другие, такие как копирование заголовка "User-Agent" из исходного POST, но это заканчивается со мной получается ошибка 500 с сервера, не знаю, почему это произойдет?

Здесь код для "GetHtmlInputValue" немного прост/базовый и может быть выполнен лучше, но: -

    private string GetHtmlInputValue(string html, string inputID)
    {
        string valueDelimiter = "value=\"";

        int namePosition = html.IndexOf(inputID);
        int valuePosition = html.IndexOf(valueDelimiter, namePosition);

        int startPosition = valuePosition + valueDelimiter.Length;
        int endPosition = html.IndexOf("\"", startPosition);

        return html.Substring(startPosition, endPosition - startPosition);
    }

Ответ 1

Если вы правильно поняли, тогда выбор элемента в раскрывающемся списке приведет к выполнению POST, а сервер изменяет доступные параметры в другой части формы. Затем сервер включит текущее значение раскрывающегося списка в поле значения __VIEWSTATE.

Когда вы выполняете очистку, вы должны убедиться, что __VIEWSTATE содержит требуемое значение для раскрывающегося списка. Чтобы продолжить исследование, попробуйте декодировать область просмотра с сервера и посмотреть, какие значения будут отправлены назад.