Перейти к основному контенту
Поддержка
Войдите с помощью учетной записи Майкрософт
Войдите или создайте учетную запись.
Здравствуйте,
Выберите другую учетную запись.
У вас несколько учетных записей
Выберите учетную запись, с помощью которой нужно войти.

ASP.NET поддержки голосовой почты

Динамические обновления страниц с помощью XMLHTTP

Чтобы настроить этот столбец в соответствии со своими потребностями, мы хотим пригласить вас отправить свои идеи по интересу темам и вопросам, которые вы хотите увидеть в последующих статьях базы знаний и столбцах голосовой поддержки. Вы можете отправить свои идеи и отзывы с помощью формы "Попросить об этом". В нижней части этого столбца также есть ссылка на форму.

ВВЕДЕНИЕ

Один из моих любимых способов учиться в веб-приложении — посмотреть, как моя моя мама перемещается по веб-сайту. Она вполне может обойти Интернет, но мало знает о технических аспектах низкоуровневого уровня (что она называет "слишком ровными вещи"), из-за чего все это работает.



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



Разработчики приложения могли легко решить безотносимый уровень, если они извлекли данные только с помощью XMLHTTP, а не для публикации назад. Это и есть столбец этого месяца. Я покажу вам, как с помощью XMLHTTP обновить часть веб-страницы данными из веб-службы Microsoft ASP.NET, не делая ответов. Это действительно здорово! Верь мне.

Общие сведения

XMLHTTP отправляет запрос от клиента на веб-сервер и возвращает остров данных XML. В зависимости от структуры полученного XML-фрагмента можно использовать XSLT или DOM XML для обработки и привязки части страницы к этим данным. Это очень мощный метод.

NoteMicrosoft предлагает поведение веб-службы для Internet Explorer, что упрощает асинхронные вызовы ASP.NET веб-службам. Однако это поведение не поддерживается и это не лучший способ обновить страницу асинхронно. Вместо этого следует использовать XMLHTTP!


В примере, который я буду работать в этом столбце, я выберу три веб-службы для вызова веб-ASP.NET через XMLHTTP. Веб-служба запросит базу данных "Northwind" на локальном SQL Server и возвратит клиенту Набор данных в виде DIFFGRAM XML. Затем я буду использовать doM XML для анализа данных XML и динамического обновления части страницы. Все это будет сделано без публикации назад.

Веб-служба

Используемая веб-служба называется DynaProducts. Это базовая веб ASP.NET-служба, написанная в C#, которая содержит три метода.

  • GetCategories — возвращает набор данных, содержащий все категории в таблице Categories.

  • GetProducts — возвращает набор данных, содержащий все продукты категории, переданные методу.

  • GetProductDetails — возвращает набор данных, содержащий сведения о продукте, productID которого передается методу.

HTML-страница

Первое, что может вас зависть в этом примере, — это страница, которую я обновляю, хотя веб-служба ASP.NET не является ASP.NET страницей. Это обычная HTML-страница. Однако на страницу добавлено большое количество клиентских javaScript, и именно этот сценарий совершает звонки в веб-службу.



Рассмотрим первый фрагмент кода на HTML-странице.

var objHttp;
var objXmlDoc;

function getDataFromWS(methodName, dataSetName, wsParamValue, wsParamName)
{

// create the XML object
objXmlDoc = new ActiveXObject("Msxml2.DOMDocument");

if (objXmlDoc == null)
{
alert("Unable to create DOM document!");

} else {

// create an XmlHttp instance
objHttp = new ActiveXObject("Microsoft.XMLHTTP");


// Create the SOAP Envelope
strEnvelope = "<soap:Envelope xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +

" xsd=\"http://www.w3.org/2001/XMLSchema\"" +

" soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +

" <soap:Body>" +

" <" + methodName + " xmlns=\"http://jimcoaddins.com/DynaProducts\">" +

" </" + methodName + ">" +

" </soap:Body>" +

"</soap:Envelope>";


// Set up the post
objHttp.onreadystatechange = function(){

// a readyState of 4 means we're ready to use the data returned by XMLHTTP
if (objHttp.readyState == 4)
{

// get the return envelope
var szResponse = objHttp.responseText;

// load the return into an XML data island
objXmlDoc.loadXML(szResponse);

if (objXmlDoc.parseError.errorCode != 0) {
var xmlErr = objXmlDoc.parseError;
alert("You have error " + xmlErr.reason);
} else {

switch(dataSetName)
{
case "CategoriesDS":
processCategory();
break;

case "ProductsDS":
processProducts();
break;

case "ProductDetailDS":
processProductDetails();
break;

}
}

}
}

var szUrl;
szUrl = "http://dadatop/wsXmlHttp/DynaProducts.asmx/" + methodName;

if (wsParamValue != null)
{

szUrl += "?" + wsParamName + "=" + wsParamValue;
}

// send the POST to the Web service
objHttp.open("POST", szUrl, true);
objHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
objHttp.send(strEnvelope);
}
}

Это самый большой фрагмент кода на странице, и я хочу подробно и подробно его прогонать, чтобы вы могли понять, что происходит.



В верхней части этого блока сценария были созданы две переменные: objHttp и objXmlDoc. Это переменные, которые будут применяться для объекта XMLHTTP и объекта DOM XML. Непосредственно после этого определение функции getDataFromWS. Это функция, которая отвечает за звонок веб-службе на стороне клиента. Он имеет следующие четыре аргумента, два из которых являются необязательными:

  • methodName — имя метода для вызова веб-службы.

  • dataSetName — имя набора данных, возвращаемого веб-службой.

  • wsParamValue — значение параметра, который передается веб-службе, если применимо. (Необязательно)

  • wsParamName — имя параметра, который передается веб-службе, если применимо. (Необязательно)

Разберем функцию getDataFromWS по частям и обсудим каждый из них. Вот первый фрагмент:

// create the XML object
objXmlDoc = new ActiveXObject("Msxml2.DOMDocument");

if (objXmlDoc == null)
{
alert("Unable to create DOM document!");

} else {

// create an XMLHTTP instance
objHttp = new ActiveXObject("Microsoft.XMLHTTP");

В этом блоке кода создаются объектЫ XMLHTTP и документы XML. Теперь я приступить к созданию конверта SOAP.

// Create the SOAP Envelope
strEnvelope = "<soap:Envelope xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +

" xsd=\"http://www.w3.org/2001/XMLSchema\"" +

" soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +

" <soap:Body>" +

" <" + methodName + " xmlns=\"http://jimcoaddins.com/DynaProducts\">" +

" </" + methodName + ">" +

" </soap:Body>" +

"</soap:Envelope>";

В этом коде конверт SOAP назначается строковой переменной, чтобы его можно было передать веб-службе. На самом деле очень легко узнать, как отформатирование конверта SOAP для веб-службы. Просто перейдите в веб-службу и выберите один из способов, чтобы просмотреть конверт SOAP для этого метода. Например, вот что я вижу при просмотре метода GetCategories веб-службы wsXMLHTTP, созданной для этой статьи:заме желтая текстASP.NET сообщает, как конверт SOAP должен быть отформатирован для HTTP POST и



HTTP GET. В примере, представленом в этой статье, я буду использовать HTTP POST.



Пока все в порядке. Теперь рассмотрим следующий раздел кода.

// Set up the post
objHttp.onreadystatechange = function(){

// a readyState of 4means we're ready to use thedata returned byXMLHTTP
if (objHttp.readyState == 4)
{

// getthe return envelope
varszResponse= objHttp.responseText;

// loadthe return into an XML data island
objXmlDoc.loadXML(szResponse);

if (objXmlDoc.parseError.errorCode != 0) {
var xmlErr =objXmlDoc.parseError;
alert("You have error " + xmlErr.reason);
}
else
{

switch(dataSetName)
{
case "CategoriesDS":
processCategory();
break;
case "ProductsDS":
processProducts();
break;
case "ProductDetailDS":
processProductDetails();
break;

}
}

При запросе через XMLHTTP объект XMLHTTP использует свойство readyState для отслеживания состояния запроса. Когда все данные будут получены от веб-службы, свойство readyState изменится на 4. Свойство onreadystatechange объекта XMLHTTP позволяет настроить функцию callback, которая будет вызываться при внесении изменений в свойство readyState. Убедившись в том, что данные получены полностью, я могу не действовать с данными до тех пор, пока не буду готов.



После того как все данные будут получены, я создам остров данных XML с ответом, используя свойство responseText. Как известно, ответ веб-службы имеет формат XML. В этом случае мы возвращаем набор данных Microsoft ADO.NET DataSet.



В следующем разделе этого блока кода для вызова соответствующей функции на основе имени dataSet, возвращаемого веб-службой, используется коммутатор. Чуть позже я войду в код этих функций.


Теперь рассмотрим код, который выполняет запрос XMLHTTP.

var szUrl;
szUrl = "http://dadatop/wsXmlHttp/DynaProducts.asmx/" + methodName;

if (wsParamValue != null)
{

szUrl += "?" + wsParamName + "=" + wsParamValue;
}

// send the POST to the Web service
objHttp.open("POST", szUrl, true);
objHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
objHttp.send(strEnvelope);

Переменная szUrl содержит URL-адрес, который используется для вызова веб-службы с целях ясности. После этого у меня есть утверждение IF, которое подбирает параметры, которые передаются как значение QueryString. В своей среде может потребоваться добавить параметры в конверт SOAP. В любом случае все в порядке.



Открытый метод объекта XMLHTTP называется следующим. Первые три аргумента открытого метода метод, URL-адрес и boolean value, которые указывает, является ли звонок асинхронным.
Важно, если вы звоните асинхронно, как я здесь, необходимо настроить функцию callback с помощью свойства onreadystatechanged.

После того как заглавный запрос для типа контента заведомо настроен, я отправлю запрос в виде конверта SOAP, используя ранее заполненную строковую переменную.



Теперь весь код, из-за чего создается запрос XMLHTTP, теперь не отошел. Теперь рассмотрим код, который обрабатывает интерфейс в браузере и обрабатывает ответ при вызове веб-службы.

Сначала посмотрим на функцию, которая называется при первой загрузке страницы.

function getCategories()
{

var func = "getDataFromWS('GetCategories', 'CategoriesDS')";
document.all.lblCategoryDropdown.innerText =
"Please wait while data is retrieved...";
window.setTimeout(func, 1);

}

Первым делом я создаю переменную для хранения подписи функции getDataFromWS. Я хочу вызвать функцию getDataFromWS в конце функции window.setTimeout. Этот подход предназначен для отображения состояния пользователя во время ожидания завершения вызова веб-службы. Обратите внимание, что я изменяю внутреннюютекст DIV, чтобы отобразить сообщение о том, что данные извлекаются. Затем запланировать функцию getDataFromWS с помощью вызова window.setTimeout и настроить ее на запуск в миллисекунд.

Обработка ответа веб-службы

Помните ранее, что для настройки функции callback использовалось свойство onreadystatechanged. Следует также помнить, что функция callback содержит коммутатор, который вызывает определенную функцию на основе имени DataSet. В этом случае набор данных будет называться CategoriesDS. Таким образом, функция processCategory будет вызываться из функции callback. Давайте посмотрим на эту функцию, чтобы узнать, как использовать doM XML для разбиения ответов из веб-службы.

function processCategory()
{

// get an XML data island with the category data
objNodeList = objXmlDoc.getElementsByTagName("Categories");

// add default value to the drop-down
document.forms[0].drpCategory.options[0] = new Option("Select a Category", 0);

// walk through the nodeList and populate the drop-down
for (var i = 0; i < objNodeList.length; i++)
{
var dataNodeList;
var textNode;
var valueNode;

dataNodeList = objNodeList[i].childNodes;
valueNode = dataNodeList.item(0);
textNode = dataNodeList.item(1);

document.forms[0].drpCategory.options[i + 1] =
new Option(textNode.text, valueNode.text);
document.all.lblCategoryDropdown.innerText = "Select a Category:";
document.forms[0].drpCategory.style.visibility = "visible";

}

}

Помните, что функция getDataFromWS загрузит XML из ответа в объект objXmlDoc. В функции ProcessCategory я принимаю XML и пробираю его, чтобы заполнить drop-down категории.



Первым делом нужно создать объект IXMLDOMNodeList, используя часть ответа XML. Набор данных, который я возвращаю из звонка веб-службы, возвращается в качестве diffgram, и единственное, что меня интересует, — это данные из dataTable, вставленные в Набор данных. Для этого можно создать объект IXMLDOMNodeList из блока XML, который содержит dataTable.



Если посмотреть код веб-службы, вы увидите, что я создал dataTable с именем Categories и добавил его в DataSet. При возврате XML из веб-службы набор данных содержится в блоке <CategoriesDS>, а каждая строка из dataTable содержится в отдельных блоках <Categories>, как показано в XML-файле ниже.

Следующие файлы можно скачать из Центра загрузки Майкрософт:Загрузить
скачайте GetCategories.xml пакета.
Загрузить скачайте WSXMLHTTP.exe пакета прямо сейчас.Для получения дополнительных сведений о скачии файлов службы поддержки Майкрософт щелкните номер следующей статьи, чтобы просмотреть статью в базе знаний Майкрософт:

119591 Как получить файлы поддержки Майкрософт от веб-служб, которые корпорация Майкрософт проверяла этот файл
на вирусы. Корпорация Майкрософт использует самые последние на момент публикации файла версии антивирусного программного обеспечения. Файл хранится на защищенных серверах, что предотвращает его несанкционированное изменение.


Чтобы получить XML-блок, содержащий эту возможность, используйте следующий код:

objNodeList = objXmlDoc.getElementsByTagName("Categories");

Это возвращает объект IXMLDOMNodeList, содержащий все <категории> узла. Затем я выберу цикл для итерации по этому списку.

// walk through the nodeList and populate the drop-down
for (var i = 0; i < objNodeList.length; i++)
{
var dataNodeList;
var textNode;
var valueNode;

dataNodeList = objNodeList[i].childNodes;
valueNode = dataNodeList.item(0);
textNode = dataNodeList.item(1);

document.forms[0].drpCategory.options[i + 1] =
new Option(textNode.text, valueNode.text);
document.all.lblCategoryDropdown.innerText = "Select a Category:";
document.forms[0].drpCategory.style.visibility = "visible";

}

Я уже знаю, что у каждого узла <Category> будет два узла: узел <ID> и узел <CategoryName>. Поэтому первым делом нужно создать новый список IXMLDOMNodeList и заполнить его потомками текущего узла <категорий>.

dataNodeList = objNodeList[i].childNodes;

Затем я использую метод элемента для доступа к обоим узлам, которые нужно заполнить. Первый узел содержит поле CategoryID из базы данных, а второй узел содержит поле CategoryName из базы данных. Я создал объект Option, настроил для текста имяКатегории, устанавливаю значение в кодКатегории и добавляю его в drop-down drpCategory. В коде, используемом в оставшихся функциях, используется тот же метод, что и для получения необходимых данных из ответа XML и заполнения частей страницы.

NoteSince we're dealing with small amounts of data here, using the DOM is a great way to pull out the data we need. Если вы имеете дело с большим объемом данных, вместо них можно использовать XSLT.

Как сделать так, чтобы все работало

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

Развертывание веб-службы

Чтобы развернуть веб ASP.NET-службу, просто закрепите вложенный образец веб-службы в корню веб-сервера. Затем необходимо открыть код для DynaProducts.asmx и изменить строку подключения. По крайней мере, вам потребуется ввести пароль SA. После внося этого изменения повторно соберем веб-службу.

Развертывание HTML-файла

HTML-файл содержит переменную szUrl, которая содержит URL-адрес веб-службы. Эта переменная находится в функции getDataFromWS в нижней части функции. Вам потребуется изменить этот URL-адрес для веб-службы, развернутой выше.


После развертывания веб-службы и HTML-файла перейдите к HTML-файлу. При загрузке в него будет загружен первый XMLHTTP-запрос веб-службы. После заполнения выберите категорию, чтобы прикнуть следующий запрос XMLHTTP, который заполнит drop-down Products. При выборе продукта из drop-down Products в таблице будут заполнены данные о нем.



Обратите внимание на то, что страница не опубликована ни при каких из этих запросов XMLHTTP. В этом и есть прелесть запросов XMLHTTP. Если бы это было сделано на большой странице, на странице также сохранялась бы положение прокрутки без мигания. Если вы спросите меня, это очень мощный инструмент.



Еще одно: в этой статье для запроса веб-службы использовался XMLHTTP. С его легкостью можно было бы запросить asPX-страницу или ASP-страницу. Возможности использования этой технологии безграничны. Я надеюсь, что вы найдете XMLHTTP полезным для дальнейшей разработки веб-приложений.

Как всегда, вы можете отправлять идеи по темам, которые вы хотите решить, в будущих столбцах или в базе знаний Майкрософт с помощью формы Ask For It.

Нужна дополнительная помощь?

Нужны дополнительные параметры?

Изучите преимущества подписки, просмотрите учебные курсы, узнайте, как защитить свое устройство и т. д.

В сообществах можно задавать вопросы и отвечать на них, отправлять отзывы и консультироваться с экспертами разных профилей.

Были ли сведения полезными?

Насколько вы удовлетворены качеством перевода?
Что повлияло на вашу оценку?
После нажатия кнопки "Отправить" ваш отзыв будет использован для улучшения продуктов и служб Майкрософт. Эти данные будут доступны для сбора ИТ-администратору. Заявление о конфиденциальности.

Спасибо за ваш отзыв!

×