Przejdź do głównej zawartości
Pomoc techniczna
Zaloguj się przy użyciu konta Microsoft
Zaloguj się lub utwórz konto.
Witaj,
Wybierz inne konto.
Masz wiele kont
Wybierz konto, za pomocą którego chcesz się zalogować.

ASP.NET Głos pomocy technicznej

Dynamiczne aktualizacje stron przy użyciu protokołu XMLHTTP

Aby dostosować tę kolumnę do swoich potrzeb, chcemy zaprosić Cię do przesyłania pomysłów dotyczących tematów, które Cię interesują, oraz tematów, które chcesz zobaczyć w przyszłych artykułach z bazy wiedzy Knowledge Base i kolumnach Głos pomocy technicznej. Swoje pomysły i opinie możesz przesyłać przy użyciu formularza Pytaj o to. U dołu tej kolumny znajduje się również link do formularza.

WPROWADZENIE

Jedną z moich ulubionych metod nauki użyteczności aplikacji sieci Web jest obserwowanie, jak moja żona porusza się po witrynie internetowej. Potrafi dość dobrze korzystać z Internetu, ale niewiele wie o jego aspektach technicznych (tak zwątając przy tym nudne), które sprawiają, że wszystko działa.



Ostatniego wieczór oglądałem moją żonę na temat aplikacji do handlu elektronicznego jednego z chłopców. Była na liście produktów, korzystając z wielu list rozwijanych, z których każda stanowi część wyboru dokonanego wcześniej. Gdy kliknął element na każdej liście rozwijanej, strona została ponownie opublikowana w celu uzyskania danych do następnej listy rozwijanej. Jej wrażenia były frustrujące, ponieważ jej wrażenie było związane z długim czasem ze względu na publikację.



Poziom frustracji, z którym miała do czynienia, mógł być łatwo złagodzone przez deweloperów aplikacji, jeśli używali oni języka XMLHTTP tylko do pobierania danych zamiast publikowania ich ponownie. O to chodzi w kolumnie z tego miesiąca. Pokażę, jak za pomocą protokołu XMLHTTP zaktualizować część strony sieci Web przy użyciu danych z usługi sieci Web usługi Microsoft ASP.NET bez konieczności cofniania wpisu. To będzie naprawdę świetne! Zaufaj mi.

Ogólne omówienie

Język XMLHTTP działa przez wysłanie żądania do serwera sieci Web od klienta i zwrócenie wyspy danych XML. W zależności od struktury otrzymanego kodu XML można użyć języka XSLT lub XML DOM, aby manipulować nim i powiązać części strony z danymi. To bardzo zaawansowana technika.

NoteMicrosoft oferuje zachowanie usługi sieci Web dla programu Internet Explorer, które wykonuje asynchroniczne połączenia z ASP.NET sieci Web szybkim i łatwym. Jednak to zachowanie nie jest obsługiwane i nie jest najlepszym sposobem na asynchroniczne aktualizowanie strony. Zamiast tego należy używać protokołu XMLHTTP!


W tym przykładzie, który przejdę w tej kolumnie, nakierujem na trzy wywołania usługi sieci Web do usługi sieci ASP.NET sieci Web za pośrednictwem protokołu XMLHTTP. Usługa sieci Web zapyta bazę danych Northwind w lokalnym programie SQL Server i zwróci klientowi zestaw danych w postaci dyfgramu XML. Następnie użyję dom xml do analizowania danych XML i dynamicznego aktualizowania części strony. Wszystko to zostanie zrobione bez cofniania wpisu.

Usługa sieci Web

Usługa sieci Web, która będzie używać, nosi nazwę DynaProducts. Jest to podstawowa ASP.NET sieci Web napisana w języku C# i która zawiera następujące trzy metody.

  • GetCategories — zwraca zestaw danych zawierający wszystkie kategorie w tabeli Kategorie.

  • GetProducts — zwraca zestaw danych zawierający wszystkie produkty z kategorii, które są przekazywane do metody.

  • GetProductDetails — zwraca zestaw danych zawierający szczegóły dotyczące produktu, którego wartość ProductID jest przekazywana do metody.

Strona HTML

Pierwszą rzeczą, która może Cię przeoczyć w tym przykładzie, jest to, że strona, którą aktualizuję, ASP.NET nie jest stroną internetową ASP.NET sieci Web. To zwykła strona HTML. Jednak do strony dodano do strony sporo kodu JavaScript po stronie klienta i właśnie ten skrypt powoduje połączenia z usługą sieci Web.



Przyjrzyjmy się pierwszeowi fragmentowi kodu ze strony 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);
}
}

To jest największy fragment kodu na stronie i chcę go szczegółowo ominą, aby zrozumieć, co się dzieje.



U góry tego bloku skryptu zostały utworzone dwie zmienne: objHttp i objXmlDoc. Są to zmienne, których będę używać dla obiektu XMLHTTP i obiektu XML DOM. Zaraz potem będzie to definicja funkcji getDataFromWS. Jest to funkcja, która jest odpowiedzialna za wywołanie po stronie klienta do usługi sieci Web. Przyjmuje następujące cztery argumenty, z których dwa są opcjonalne:

  • methodName — nazwa metody, która ma być wywołana w usłudze sieci Web.

  • dataSetName — nazwa zestawu danych zwracana przez usługę sieci Web.

  • wsParamValue — wartość parametru przekazywanego do usługi sieci Web, jeśli ma zastosowanie. (Opcjonalnie)

  • wsParamName — nazwa parametru przekazywanego do usługi sieci Web, jeśli ma zastosowanie. (Opcjonalnie)

Rozbijmy funkcję getDataFromWS na części i omówimy każdą z nich. Oto pierwszy fragment:

// 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");

Ten blok kodu tworzy obiekt XMLHTTP i obiekt dokumentu XML. Następnie rozpoczynam tworzenie koperty protokołu 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>";

W tym kodzie przypisuję kopertę protokołu SOAP do zmiennej ciągu, aby można było przekazać ją do usługi sieci Web. Faktycznie dosyć łatwo można dowiedzieć się, jak sformatować kopertę protokołu SOAP dla usługi sieci Web. Po prostu przejdź do usługi sieci Web i kliknij jedną z metod, aby wyświetlić kopertę protokołu SOAP dla tej metody. Na przykład oto, co widzę podczas przeglądania metody GetCategories usługi sieci Web wsXMLHTTP, która została utworzona dla tego artykułu: program tekst alternatywnyASP.NET informuje o tym, jak należy sformatować kopertę protokołu SOAP dla wpisów HTTP i



HTTP GET. W przykładzie przedstawionym w tym artykule będę używać protokołu HTTP POST.



Jak na razie dobrze idzie. Teraz przyjrzyjmy się następnej sekcji kodu.

// 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;

}
}

W przypadku żądania przy użyciu protokołu XMLHTTP obiekt XMLHTTP używa właściwości readyState do śledzenia stanu żądania. Po otrzymaniu wszystkich danych z usługi sieci Web właściwość readyState zmienia się na wartość 4. Właściwość onreadystatechange obiektu XMLHTTP umożliwia skonfigurowanie funkcji callback, która będzie wywoływana po zmianie właściwości readyState. Upewniając się, że dane zostały odebrane w całości, mogę nadal nie działać na te dane, dopóki nie będą gotowe.



Gdy wszystkie dane zostały odebrane, za pomocą właściwości Tekst Odpowiedzi tworzym mapę danych XML z odpowiedzią. Jak pewnie wiesz, odpowiedź z usługi sieci Web jest w formacie XML. W tym przypadku zwracam zestaw danych Microsoft ADO.NET DataSet.



W następnej sekcji tego bloku kodu użyto instrukcji Switch do wywołania odpowiedniej funkcji na podstawie nazwy zestawu danych zwracanej z usługi sieci Web. Nieco później przejdę do kodu tych funkcji.


Teraz przyjrzyjmy się kodowi, który faktycznie wykonuje żądanie 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);

Zmienna szUrl zawiera adres URL używany do wywołania usługi sieci Web w celu zwiększenia przejrzystości. Następnie mam instrukcje jeżeli dotyczące wszystkich parametrów przekazywanych jako wartość QueryString. W środowisku możesz zechcieć dodać parametry do koperty protokołu SOAP. W obu tych sposób działa to w porządku.



Metoda otwierania obiektu XMLHTTP jest nazywana dalej. Użyłem trzech pierwszych argumentów metody open; metoda, adres URL i wartość logiczna określająca, czy połączenie jest asynchroniczne.
Ważne: jeśli właśnie tutaj wytyczasz asynchroniczne wywołanie, musisz skonfigurować funkcję callback za pomocą właściwości onreadystatechanged.

Po skonfigurowaniu nagłówka żądania dla typu zawartości wysyłam żądanie jako kopertę PROTOKOŁU SOAP, używając zmiennej ciągu, która była wcześniej wypełniana.



Teraz przeszliśmy przez cały kod, który składa żądanie XMLHTTP. Teraz przyjrzyjmy się kodowi, który obsługuje interfejs w przeglądarce i obsługuje odpowiedź z połączenia usługi sieci Web.

Najpierw przyjrzymy się funkcji, która jest wywoływana podczas ładowania strony po raz pierwszy.

function getCategories()
{

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

}

Pierwszą rzeczą, jaką robię w tej funkcji, jest utworzenie zmiennej do przechowywania podpisu funkcji dla funkcji getDataFromWS. Dzieje się tak, ponieważ na końcu tej funkcji przejdę do ustawienia window.setTimeout, aby wywołać funkcję getDataFromWS. Celem tego rozwiązania jest umożliwienie użytkownikowi wyświetlenia jego stanu w trakcie oczekiwania na ukończenie połączenia usługi sieci Web. Zwróć uwagę, że zmieniam tekst wewnętrzny DZIEL w celu wyświetlenia komunikatu wskazującego, że dane są pobierane. Następnie zaplanuję uruchomienie funkcji getDataFromWS za pośrednictwem połączenia window.setTimeout i ustawiam, aby była uruchamiana w milisekundach.

Przetwarzanie odpowiedzi usługi sieci Web

Pamiętaj, że właściwość onreadystatechanged była wcześniej używana do konfigurowania funkcji callback. Należy również pamiętać, że funkcja callback zawiera instrukcje switch, które wywołują określoną funkcję na podstawie nazwy zestawu danych. W tym przypadku naszą nazwą zestawu danych są kategorieDS. Dlatego funkcja processCategory będzie wywoływana za pomocą funkcji callback. Przyjrzyjmy się tej funkcji, aby dowiedzieć się, jak używać funkcji DOM kodu XML do analizowania odpowiedzi z usługi sieci Web.

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";

}

}

Pamiętaj, że funkcja getDataFromWS załadowała plik XML z odpowiedzi do obiektu objXmlDoc. W funkcji ProcessCategory przejmę ten język XML i analizują go, aby wypełnić pola listy rozwijanej Kategoria.



Najpierw utworzyę obiekt IXMLDOMNodeList, używając części odpowiedzi XML. Zwracany przeze mnie zestaw danych z połączenia usługi sieci Web jest zwracany jako diffgram, a jedyną częścią tej odpowiedzi, która mnie interesuje, są dane z tabeli danych wstawionych przeze mnie do zestawu danych. Mogę to zrobić, tworząc obiekt IXMLDOMNodeList z bloku XML zawierającego tabelę danych.



Gdy przyjrzysz się kodowi dla usługi sieci Web, zobaczysz, że tworzyć tabelę danych o nazwie Kategorie i dodawać ją do zestawu danych. Gdy kod XML jest zwracany z usługi sieci Web, zestaw danych jest zawarty w bloku> CategoriesDS <CategoriesDS, a każdy wiersz tabeli danych jest zawarty w osobnych blokach <> kategorii>, jak pokazano w pliku XML poniżej.

Następujące pliki są dostępne do pobrania z Centrum pobierania Microsoft:
Pobierz pobierz GetCategories.xml teraz.
Pobierz pobierz WSXMLHTTP.exe pakietu aplikacji.Aby uzyskać więcej informacji na temat pobierania plików pomocy technicznej firmy Microsoft, kliknij następujący numer artykułu, aby wyświetlić ten artykuł z bazy wiedzy Microsoft Knowledge Base:

119591 Jak uzyskać pliki pomocy technicznej firmy Microsoft z usług online, firma Microsoft skanowała ten
plik w poszukiwaniu wirusów. Firma Microsoft używa najnowszego oprogramowania do wykrywania wirusów, które było dostępne w dniu publikacji pliku. Plik jest przechowywany na serwerach z zabezpieczeniami, które pomagają zapobiec nieautoryzowanym zmianom w pliku.


Aby uzyskać blok XML zawierający tabelę danych, użyj następującego kodu:

objNodeList = objXmlDoc.getElementsByTagName("Categories");

W ten sposób zwracany jest obiekt IXMLDOMNodeList zawierający <kategorie> węźle. Następnie przechodzim iteracyjnie przez listę, używając pętli.

// 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";

}

Już wiem, że każdy węzeł <Categories> będzie miał dwa węzły, których potrzebuję: węzeł <Identyfikator> i węzeł <NazwaKategori> węzła. Dlatego najpierw utworzym nową listę IXMLDOMNode <List i wypełnię ją węzłami podrzędnymi bieżącego węzła kategorie> grupy.

dataNodeList = objNodeList[i].childNodes;

Następnie za pomocą metody elementu uzyskujem dostęp do obu węzłów, których potrzebuję, aby wypełnić swoją menu rozwijane. Pierwszy węzeł zawiera pole CategoryID z bazy danych, a drugi węzeł zawiera pole CategoryName z bazy danych. Tworzym nowy obiekt Opcja, ustawiam tekst na wartość NazwaKategorii, ustawiam wartość IdentyfikatorKategorii i dodajemy ją do listy rozwijanej drpCategory. Kod używany w pozostałych funkcjach używa tej samej metody w celu pociągnięcia potrzebnych danych z odpowiedzi XML i wypełnienia części strony.

UwagaSince mamy tu do czynienia z małymi ilościami danych, dlatego korzystanie z dom to doskonały sposób na wyciągnięcie potrzebnych danych. Jeśli masz do czynienia z dużą ilością danych, możesz zamiast tego użyć funkcji XSLT.

Jak to wszystko działa

Teraz, gdy już przejdę szczegółowe informacje o tym, jak to wszystko działa, czas sprawdzić, jak możesz użyć dołączonych plików przykładowych, aby przekonać się, jak to działa.

Wdrażanie usługi sieci Web

Aby wdrożyć ASP.NET sieci Web, po prostu rozpakować załączoną próbkę usługi sieci Web w katalogu głównym serwera sieci Web. Następnie należy otworzyć kod dynaproducts.asmx i zmienić parametrów połączenia. Co najmniej musisz wprowadzić hasło SA. Po wymknieniu tej zmiany skompilowaj ponownie usługę sieci Web.

Wdrażanie pliku HTML

Plik HTML zawiera zmienną o nazwie szUrl, która zawiera adres URL usługi sieci Web. Zmienna znajduje się w funkcji getDataFromWS w dolnej części funkcji. Musisz zmienić ten adres na adres URL usługi sieci Web wdrożonej powyżej.


Po wdrożeniu usługi sieci Web i pliku HTML przejdź do pliku HTML. Podczas ładowania lista rozwijana Kategoria zostanie wypełniona pierwszym żądaniem http XML do usługi sieci Web. Po wypełnieniu tego pola wybierz kategorię, aby wystartować z następnym żądaniem XMLHTTP, które wypełnia pole listy rozwijanej Produkty. Wybranie produktu z listy rozwijanej Produkty spowoduje wypełnienie tabeli danymi o tym produkcie.



Zwróć uwagę, że strona nie zostanie ponownie opublikowana podczas żadnych z tych żądań XMLHTTP. Tak właśnie jest w żądaniach XMLHTTP. Gdybym zrobił to na dużej stronie, ta strona również zachowywałaby swoje położenie przewijania bez "migania" u użytkownika. Jeśli o to zapytasz, to całkiem zaawansowane funkcje.



Jeszcze jedno: w tym artykule język XMLHTTP był używany do wykonywania zapytań w usłudze sieci Web. Mogę równie łatwo użyć jej do zażądania strony ASPX lub ASP. Możliwości zastosowania tej technologii są nieograniczone. Mam nadzieję, że język XMLHTTP będzie przydatny podczas tworzenia aplikacji sieci Web w przyszłości.

Jak zawsze możesz przesyłać pomysły dotyczące tematów, które chcesz zaadresować w przyszłych kolumnach lub w bazie wiedzy Microsoft Knowledge Base, przy użyciu formularza Pytaj o to.

Potrzebujesz dalszej pomocy?

Chcesz uzyskać więcej opcji?

Poznaj korzyści z subskrypcji, przeglądaj kursy szkoleniowe, dowiedz się, jak zabezpieczyć urządzenie i nie tylko.

Społeczności pomagają zadawać i odpowiadać na pytania, przekazywać opinie i słuchać ekspertów z bogatą wiedzą.

Czy te informacje były pomocne?

Jaka jest jakość języka?
Co wpłynęło na Twoje wrażenia?
Jeśli naciśniesz pozycję „Wyślij”, Twoja opinia zostanie użyta do ulepszania produktów i usług firmy Microsoft. Twój administrator IT będzie mógł gromadzić te dane. Oświadczenie o ochronie prywatności.

Dziękujemy za opinię!

×