Dynamische Aktualisierung von Webseiten mit XMLHTTP

ASP.NET Support Voice-Kolumne

Dynamische Aktualisierung von Webseiten mit XMLHTTP

Diese Spalte an Ihre Bedürfnisse anpassen möchten Laden Sie Ihre Ideen zu Themen, die Sie interessieren und sollen Probleme in Zukunft Knowledge Base-Artikeln und Support Voice Spalten angesprochen. Sie können Ihre Ideen und ihr Feedback Bitten dafür Formular senden. Außerdem wird ein Link zu diesem Formular am Ende dieser Kolumne.

Einführung

Eines meiner bevorzugten Methoden studieren Web Application Verwendbarkeit ist meine Frau Navigieren in einer Website ansehen. Sie können ihren Weg im Internet gut, aber sie weiß wenig über die einfache Technik (sie "das langweilige" nennt) stellen sie arbeiten.



Abends sah ich meiner Frau e-Commerce-Anwendung eines großen durchgehen. Sie wurde in einer Produktliste durch mehrere Dropdownlisten jeweils Menge von zuvor Drilldown. Sie klicken auf ein Element in jedem zurück zu Daten für das nächste Dropdown-Seite bereitgestellt. Die Erfahrung war für sie war ihr Eindruck, dass es aufgrund der Postbacks lange wurde.



Welche Frustration erleben sie wurde konnte problemlos verschwunden durch den Entwickler der Anwendung Wenn sie nur XMLHTTP zum Abrufen der Daten statt zurück. Das geht dieses Monats. Ich zeige Ihnen wie man XMLHTTP nutzen einen Teil einer Seite ohne Postback mit Daten aus Microsoft ASP.NET Web Service aktualisieren. Dies wird wirklich cool! Vertraue mir.

Übersicht

XMLHTTP funktioniert eine Anforderung vom Client an den Webserver senden und eine XML-Dateninsel zurückgibt. Je nach Struktur der empfangenen XML-können Sie XSLT oder XML DOM bearbeiten und Teile der Webseite an die Daten bindet. Dies ist eine extrem effiziente Methode.

Hinweis Microsoft bietet eine Webdienst-Methode für Internet Explorer, die asynchrone Webdienstaufrufe ASP.NET beschleunigt und vereinfacht. Aber dies wird nicht unterstützt und ist nicht die beste Möglichkeit, eine Webseite asynchron zu aktualisieren. Verwenden Sie stattdessen XMLHTTP!


Im Beispiel arbeite ich über in dieser Spalte werden kopiere ich ein ASP.NET Web Service über XMLHTTP drei Webdienstaufrufe. Der Webdienst fragt der Northwind-Datenbank auf dem lokalen SQL Server und ein DataSet in Form eines Diffgram an den Client zurück. Ich dann mithilfe von XML DOM die XML-Daten analysieren und Teile meiner Webseite dynamisch aktualisieren. All dies erfolgt ohne Postback.

Der Webdienst

Der Webdienst, den ich verwende Namen "DynaProducts". Es ist eine grundlegende ASP.NET Web Service in C# geschrieben und enthält die folgenden drei Methoden.

  • GetCategories – gibt einen DataSet mit alle Kategorien in der Tabelle Kategorien.
  • GetProducts – gibt ein DataSet, das alle Produkte der Kategorien enthält, die an die Methode übergeben werden.
  • GetProductDetails – gibt ein DataSet mit Informationen über das Produkt, dessen ProductID an die Methode übergeben wird.

Die HTML-Seite

Was Sie bei diesem Beispiel überraschen möglicherweise ist die Seite, die ich jedoch ASP.NET Web Service aktualisieren bin keine ASP.NET Seite. Es ist einfach eine normale HTML-Seite. Allerdings der Seite wurden Portion clientseitigen JavaScript hinzugefügt und ist das Skript, das auf den Webdienst aufruft.



Sehen wir uns das erste Stückchen Code aus der HTML-Seite.
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);
}
}
Dies ist der größte Codeabschnitt aus der Seite, und ich will darüber im Detail damit Sie verstehen, was passiert.



Am Anfang des Skriptblocks habe zwei Variablen: ObjHttp und ObjXmlDoc. Dies sind die Variablen werde, die ich für mein XMLHTTP-Objekt und mein XML DOM-Objekt verwenden. Unmittelbar danach eine Funktionsdefinition für die Funktion GetDataFromWS . Dies ist die Funktion für den clientseitigen Aufruf an den Webdienst verantwortlich. Es nimmt vier Argumente auf, von die zwei optional sind:
  • MethodName – der Name der Methode für den Webdienst aufzurufen.
  • DataSetName – der Name des Datasets, die vom Webdienst zurückgegeben wird.
  • WsParamValue – der Wert des Parameters Webdienst ggf. an. (Optional)
  • WsParamName – der Name des Parameters, der Webdienst ggf. an. (Optional)
Wir teilen die Funktion GetDataFromWS in Teilen und jeden einzeln erörtern. Hier ist der erste Schnipsel:
// 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");

Dieser Codeblock erstellt das XMLHTTP-Objekt und das XML-Dokument-Objekt. Als Nächstes erstelle ich zuerst den SOAP-Umschlag.
// Create the SOAP EnvelopestrEnvelope = "<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>";

In diesem Code habe ich eine Zeichenfolgenvariable SOAP-Envelope zuweisen, damit ich an den Webdienst übergeben werden kann. Es ist eigentlich ganz einfach, wie SOAP-Umschlag für Ihren Webdienst formatiert. Browsen Sie einfach zu dem Webdienst, und klicken Sie auf eine der Methoden, um einen SOAP-Umschlag für diese Methode finden Sie unter. Beispielsweise lautet sehe ich beim Durchsuchen der GetCategories -Methode der WsXMLHTTP-Webdienst erstellte für diesen Artikel

envelope.png

ASP.NET teilt Ihnen mit, wie der SOAP-Umschlag für ein HTTP POST und ein HTTP GET formatiert werden soll. Im Beispiel in diesem Artikel vorgestellten werde ich HTTP POST verwenden.



So weit so gut. Jetzt sehen wir uns den nächsten Codeabschnitt.
// Set up the postobjHttp.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;

}
}

Bei einer über XMLHTTP Anforderung verwendet das XMLHTTP-Objekt eine Eigenschaft ReadyState zum Nachverfolgen des Status der Anforderung. Wenn alle Daten empfangen wurden vom Webdienst, ändert sich die ReadyState -Eigenschaft den Wert 4. Onreadystatechange -Eigenschaft für das XMLHTTP-Objekt können Sie eine Rückruffunktion einrichten, die aufgerufen wird, wenn die ReadyState -Eigenschaft ändert. Sicherstellen, dass die Daten vollständig empfangen wurde, kann ich behalten auf diese Daten bis ich bereit bin.



Nachdem alle Daten empfangen wurden, erstelle ich eine XML-Dateninsel mit der Antwort mithilfe der ResponseText -Eigenschaft. Wie Sie wahrscheinlich wissen, ist die Antwort von einem Webdienst im XML-Format. In diesem Fall gebe ich ein Microsoft ADO.NET DataSet.



Im nächste Abschnitt dieses Codeblocks verwendet eine Switch-Anweisung aufrufen die entsprechende Funktion anhand der vom Webdienst zurückgegebene DataSet. Ich gehe in den Code für diese Funktionen weiter unten detailliert.


Jetzt sehen wir uns den Code, der die XMLHTTP-Anforderung tatsächlich durchführt.
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);

Variable SzUrl enthält die URL, die den Webdienst aus Gründen der Klarheit aufrufen. Dann habe ich eine If-Anweisung, die Parameter Stifte, die als Wert der Abfragezeichenfolge übergeben werden. In Ihrer Umgebung möchten Sie die Parameter der SOAP-Umschlag hinzufügen. In beiden Fällen funktioniert einwandfrei.



Anschließend wird die open-Methode des XMLHTTP-Objekts aufgerufen. Ich habe die ersten drei Argumente für die open-Methode; die Methode, die URL und einen booleschen Wert, der angibt, ob der Aufruf asynchron ist.
Wichtig Wenn Sie wie ich hier einen asynchronen Aufruf durchführen, müssen Sie eine Rückruffunktion über die Eigenschaft Onreadystatechanged einrichten.

Nachdem der Anforderungsheader für den Inhaltstyp festgelegt ist, sende ich die Anforderung als SOAP-Umschlag mit der Zeichenfolgenvariablen, die ich zuvor gefüllt.



Wir haben alle den Code jetzt, die XMLHTTP-Anforderung besteht. Nun werfen wir einen Blick auf den Code, die die Benutzeroberfläche im Browser und die Antwort vom Webdienstaufruf.

Zunächst sehen wir uns die Funktion, die beim ersten der Seite laden aufgerufen.
function getCategories(){

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

}

Was ich in dieser Funktion wird eine Variable zum Speichern der Funktionssignatur GetDataFromWSerstellen. Dies geschieht da werde window.setTimeout am Ende dieser Funktion die GetDataFromWS Funktion aufrufen. Dabei soll den Status für den Benutzer angezeigt wird, warten die Web Service-Aufruf gestatten. Beachten Sie, dass ich den InnerText div eine Meldung, dass Daten abgerufen werden. Dann plane ich die Funktion GetDataFromWS durch Aufruf window.setTimeout und lege fest, dass in einer Millisekunde ausgeführt.

Verarbeitung der Antwort des Webdienstes

Daran früher Eigenschaft Onreadystatechanged habe eine Rückruffunktion konfiguriert. Beachten Sie außerdem, dass die Rückruffunktion eine Switch-Anweisung enthält, die eine bestimmte basierend auf dem Namen des Datasets Funktion. In diesem Fall ist die DataSet-Name "CategoriesDS". Daher wird die Funktion ProcessCategory die Rückruffunktion aufgerufen. Werfen Sie einen Blick auf diese Funktion zu sehen, wie das XML-DOM um zu analysieren, die Antwort vom Webdienst.
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";

}

}

Beachten Sie, dass die Funktion GetDataFromWS XML aus der Antwort in das Objekt ObjXmlDoc geladen. In der Funktion ProcessCategory ich diese XML-Daten und analysiere sie, um das Dropdown-Menü zu füllen.



Was tun, ist ein Teil der XML-Antwort IXMLDOMNodeList -Objekt erstellen. Ich von Web Service-Aufruf Rückkehr bin DataSet wird als Diffgram zurückgegeben, und der einzige Teil der Antwort, der mich interessiert ist die Daten in das DataSet eingefügte DataTable. Ich bekomme, durch Erstellen eines IXMLDOMNodeList -Objekts aus dem XML-Block, der die DataTable enthält.



Wenn Sie sich den Code für den Webdienst ansehen, sehen Sie, erstelle ich eine DataTable mit dem Namen Kategorien DataSet hinzufügen. Wenn XML vom Webdienst zurückgegebene DataSet in einem Block < CategoriesDS > enthalten und jede Zeile aus der DataTable enthaltenen trennen Sie < Kategorien > Blöcke wie in der folgenden XML-Datei.

Die folgenden Dateien stehen zum Herunterladen im Microsoft Download Center zur Verfügung:
Download "GetCategories.xml" jetzt herunterladen
Download WSXMLHTTP.exe-Paket jetzt downloaden. Weitere Informationen zum Herunterladen von Microsoft Support-Dateien klicken Sie auf die folgenden Artikelnummer der Microsoft Knowledge Base:
119591 so erhalten Sie Microsoft Support-Dateien
Microsoft hat diese Datei auf Viren überprüft. Microsoft hat die zum Zeitpunkt der Veröffentlichung der Datei aktuell verfügbare Virenerkennungssoftware verwendet. Die Datei wird auf Servern mit erhöhter Sicherheit gespeichert, wodurch nicht autorisierten Änderungen an der Datei vorgebeugt wird.


Zu den XML-Block, der die DataTable enthält, verwenden Sie folgenden Code:
objNodeList = objXmlDoc.getElementsByTagName("Categories");
Dies gibt ein IXMLDOMNodeList -Objekt, das jeden < Categories >-Knoten enthält. Ich durchsuche dann diese Liste mithilfe einer for-Schleife.
// 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";

}

Ich weiß bereits, dass jeder Knoten < Kategorien > zwei Knoten verfügen, die ich: Knoten < ID > und < CategoryName >. Daher ist das erste, was ich neue IXMLDOMNodeList erstellen und füllen Sie es mit den untergeordneten Knoten des aktuellen Knotens < Kategorien >.
dataNodeList = objNodeList[i].childNodes;
Ich verwende dann die Item-Methode auf beiden Knoten, die ich benötige, um mein Dropdown-Menü zu füllen. Der erste Knoten enthält das Feld CategoryID aus Datenbank, der zweite Knoten das CategoryName -Feld aus der Datenbank. Ich ein neues Optionsobjekt erstellt CategoryNameden Text festlegen, legen Sie den Wert auf die CategoryIDund DrpCategory Dropdown-Liste hinzufügen. Der Code für die verbleibenden Funktionen verwendet dieselbe Methode Daten aus der XML-Antwort und Teile der Seite zu füllen.

Hinweis Da wir kleine Mengen von Daten geht, ist mit dem DOM eine hervorragende Möglichkeit, die Daten extrahieren der benötigten. Wenn Sie mit einer großen Datenmenge wurden, können Sie XSLT verwenden.

Wie es funktioniert

Jetzt an Details wie all dies funktioniert erläuterten, ist es Zeit, über die Verwendung der Beispieldateien Funktionsweise selbst anzeigen.

Bereitstellung des Webdienstes

ASP.NET Web Service bereitstellen, entpacken Sie einfach die angehängte Webdienst-Beispieldatei in das Stammverzeichnis des Webservers. Sie müssen den Code für "DynaProducts.asmx" öffnen und die Verbindungszeichenfolge ändern. Zumindest müssen Sie das SA-Kennwort eingeben. Nachdem Sie diese Änderung vorgenommen haben, kompilieren Sie den Webdienst neu.

Bereitstellen der HTML-Datei

Die HTML-Datei enthält eine Variable namens SzUrl , die URL für den Webdienst enthält. Dieser Variablen finden Sie in der Funktion GetDataFromWS am Ende der Funktion. Sie müssen die URL für den Webdienst ändern, die über bereitgestellt.


Nachdem Sie den Webdienst und die HTML-Datei bereitgestellt haben, wechseln Sie zu der HTML-Datei. Laden wird das Dropdown-Menü durch die erste XMLHTTP-Anforderung an den Webdienst aufgefüllt. Sobald, aufgefüllt wurde, wählen Sie eine Kategorie, die Dropdownliste Produkte füllt die nächste XMLHTTP-Anforderung starten. Durch Auswahl eines Produkts aus der Dropdownliste Produkte füllt eine Tabelle mit Daten zu diesem Produkt.



Beachten Sie, dass die Seite nicht in diese Anfragen XMLHTTP gebucht werden. Das ist das Schöne XMLHTTP-Anfragen. Wenn ich auf einer großen Seite Dies hatte, wäre Seite auch deren Bildlaufposition unterhalten ohne "blinken" auf den Benutzer. Wenn Sie mich Fragen, ist etwas anhören!



Noch etwas: in diesem Artikel ich XMLHTTP verwendet, um einen Webdienst abzufragen. Ich hätten einfach sie eine Anforderung für eine ASPX-Seite oder einer ASP-Seite. Die wie dieser Technik lassen sind endlos. Ich hoffe, Sie XMLHTTP in Ihrem zukünftigen Webanwendungsentwicklung hilfreich.
Wie immer können Sie Ideen zu Themen möchten in Zukunft Spalten behandelt oder in der Microsoft Knowledge Base mit Bitten dafür bilden.
Eigenschaften

Artikelnummer: 893659 – Letzte Überarbeitung: 16.01.2017 – Revision: 2

Feedback