Пожалуйста, несите меня за это слегка длинное описание, но у меня возникла странная проблема с отображением С# на странице веб-форм 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);
}