Logg på med Microsoft
Logg på, eller opprett en konto.
Hei,
Velg en annen konto.
Du har flere kontoer
Velg kontoen du vil logge på med.

ASP.NET støtte for tale

Dynamiske sideoppdateringer ved hjelp av XMLHTTP

Hvis du vil tilpasse denne kolonnen etter behov, vil vi invitere deg til å sende inn ideer om emner som interesserer deg og problemer som du vil se, i fremtidige Knowledge Base-artikler og støttekolonner. Du kan sende ideer og tilbakemeldinger ved hjelp av Be om det-skjemaet. Det er også en kobling til skjemaet nederst i denne kolonnen.

INNLEDNING

En av mine favorittmåter for å studere brukervennligheten til nettprogrammet, er å se konen navigere rundt på et nettsted. Hun kan gjøre veien på Internett ganske bra, men hun vet lite om de tekniske aspektene på lavnivå (det hun kaller «de kjedelige tingene») som får det til å fungere.



En siste kveld ser jeg at konen min bruker en e-handelsapplikasjon fra en av de store gutter. Hun drillet ned i en produktoppføring ved hjelp av flere rullegardinlister. Hver av dem foringer seg fra utvalget som ble gjort tidligere. Da hun klikket på et element i hver rullegardin, la siden ut igjen for å hente data for den neste rullegardinlisten. Opplevelsen var frustrerende for henne fordi inntrykket hennes tok lang tid på grunn av tilbakeleggingen av innlegget.



Frustrasjonen hun opplevde, kunne enkelt ha blitt alleviated av utviklerne av programmet hvis de bare brukte XMLHTTP til å hente dataene i stedet for å publisere tilbake. Det er dette denne månedens kolonne handler om. Jeg vil vise deg hvordan du bruker XMLHTTP til å oppdatere en del av en nettside med data fra en Microsoft ASP.NET-nettjeneste uten å gjøre et innlegg tilbake. Dette blir virkelig kult! stol på meg.

Generell oversikt

XMLHTTP fungerer ved å sende en forespørsel til nettserveren fra klienten og returnere en XML-dataøya. Avhengig av strukturen til XML-filen som mottas, kan du bruke XSLT eller XML DOM til å manipulere den og binde deler av siden til disse dataene. Dette er en svært kraftig teknikk.

NoteMicrosoft tilbyr en virkemåte for nettjenesten for Internet Explorer som gjør asynkrone anrop til ASP.NET nettjenester raskt og enkelt. Denne virkemåten støttes imidlertid ikke, og det er ikke den beste måten å oppdatere en side asynkront på. Du bør bruke XMLHTTP i stedet!


I eksemplet vil jeg arbeide meg gjennom i denne kolonnen, foretar jeg tre webtjenesteanrop til en nettjeneste som ASP.NET XMLHTTP. Nettjenesten spør Northwind-databasen på den lokale SQL Server, og returnerer et datasett til klienten i form av et XML-diffgram. Jeg vil deretter bruke XML DOM til å analysere XML-dataene og oppdatere deler av siden dynamisk. Alt dette gjøres uten et innlegg tilbake.

Nettjenesten

Nettjenesten som jeg skal bruke, heter DynaProducts. Det er en grunnleggende ASP.NET nettjeneste som er skrevet i C# og som inneholder følgende tre metoder.

  • GetCategories – Returnerer et datasett som inneholder alle kategoriene i Kategorier-tabellen.

  • GetProducts – Returnerer et datasett som inneholder alle produkter av kategorien som sendes til metoden.

  • GetProductDetails – Returnerer et datasett som inneholder detaljer om produktet der ProduktID sendes til metoden.

HTML-siden

Det første som kan slå deg om dette eksemplet, er at siden jeg oppdaterer selv om ASP.NET-nettjenesten ikke er en ASP.NET side. Det er bare en vanlig HTML-side. Men jeg har lagt til en rimelig mengde JavaScript-klientside på siden, og det er det skriptet som ringer til nettjenesten.



La oss se på den første kodesnutten fra HTML-siden.

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);
}
}

Dette er den største koden fra siden, og jeg vil gå gjennom den i detalj, slik at du forstår hva som skjer.



Øverst i denne skriptblokken opprettet jeg to variabler: objHttp og objXmlDoc. Dette er variablene jeg vil bruke for XMLHTTP-objektet og XML DOM-objektet. Umiddelbart etter det er funksjonsdefinisjonen for getDataFromWS-funksjonen. Dette er funksjonen som er ansvarlig for å foreta anropet til nettjenesten i klienten. Det tar følgende fire argumenter, der to er valgfrie:

  • methodName – Navnet på metoden som skal ringes på nettjenesten.

  • dataSetName – Navnet på DataSet som returneres av nettjenesten.

  • wsParamValue – verdien til parameteren som sendes til nettjenesten hvis aktuelt. (Valgfritt)

  • wsParamName – Navnet på parameteren som sendes til nettjenesten hvis aktuelt. (Valgfritt)

La oss dele getDataFromWS-funksjonen opp i deler og diskutere hver enkelt. Her er den første snutten:

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

Denne kodeblokken oppretter XMLHTTP-objektet og XML-dokumentobjektet. Deretter begynner jeg å opprette SOAP-konvolutten.

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

I denne koden tilordner jeg SOAP-konvolutten til en strengvariabel slik at jeg kan sende den videre til nettjenesten. Det er faktisk ganske enkelt å oppdage hvordan du formaterer SOAP-konvolutten for nettjenesten. Bare bla til nettjenesten, og klikk en av metodene for å se en SOAP-konvolutt for denne metoden. Her er for eksempel det jeg ser når jeg blar til GetCategories-metoden for wsXMLHTTP-nettjenesten som jeg opprettet for denne artikkelen:alternativ tekstASP.NET forteller deg hvordan SOAP-konvolutten skal formateres for et HTTP POST- og



HTTP GET-format. I eksemplet som vises i denne artikkelen, bruker jeg HTTP POST.



så langt, alt vel. La oss nå se på neste del av koden.

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

}
}

Når en forespørsel er foretatt via XMLHTTP, bruker XMLHTTP-objektet en readyState-egenskap til å spore statusen til forespørselen. Når alle dataene har blitt mottatt tilbake fra nettjenesten, endres ReadyState-egenskapen til en verdi på 4. Egenskapen onreadystatechange for XMLHTTP-objektet lar deg konfigurere en tilbakeringingsfunksjon som kalles når readyState-egenskapen endres. Ved å sikre at dataene er mottatt i sin helhet, kan jeg hindre at disse dataene opptrer på den måten til jeg er klar.



Når alle dataene er mottatt, oppretter jeg en XML-dataøya med svaret ved hjelp av ResponseText-egenskapen. Som du sannsynligvis vet, er svaret fra en nettjeneste i XML-format. I dette tilfellet returnerer jeg et Microsoft ADO.NET DataSet.



Den neste delen av denne kodeblokken bruker en brytersetning til å kalle opp riktig funksjon basert på navnet på DataSet som returneres fra nettjenesten. Jeg går inn i koden for disse funksjonene litt senere.


La oss nå se på koden som faktisk utfører XMLHTTP-forespørselen.

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

Variabelen szUrl inneholder nettadressen som brukes til å kalle opp nettjenesten for klarhet. Jeg har deretter en IF-setning som takler parametere som sendes som en QueryString-verdi. I miljøet vil du kanskje legge til parameterne i SOAP-konvolutten. Uansett vil det fungere fint.



Den åpne metoden for XMLHTTP-objektet kalles neste. Jeg har brukt de tre første argumentene for den åpne metoden. metoden, nettadressen og en boolsk verdi som angir om anropet er asynkront.
Viktig Hvis du foretar et asynkront anrop mens jeg er her, må du konfigurere en tilbakeringingsfunksjon via onreadystatechanged-egenskapen.

Når forespørselshodet for innholdstypen er angitt, sender jeg forespørselen som en SOAP-konvolutt ved hjelp av strengvariabelen jeg fylte ut tidligere.



Vi har nå gått gjennom all koden som gjør XMLHTTP-forespørselen. La oss nå ta en titt på koden som håndterer grensesnittet i nettleseren, og som håndterer svaret fra nettjenesteanropet.

Først skal vi se på funksjonen som kalles når siden lastes inn første gang.

function getCategories()
{

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

}

Det første jeg gjør i denne funksjonen, er å opprette en variabel som lagrer funksjonssignaturen for getDataFromWS. Jeg gjør dette fordi jeg skal ringe window.setTimeout på slutten av denne funksjonen for å kalle opp getDataFromWS-funksjonen. Hensikten med denne fremgangsmåten er å la meg vise statusen til brukeren mens jeg venter på at nettjenesteanropet skal fullføres. Legg merke til at jeg endrer innerteksten for en DIV for å vise en melding om at dataene hentes. Jeg planlegger deretter getDataFromWS-funksjonen gjennom window.setTimeout-samtalen, og jeg angir at den skal kjøre i én millisekunder.

Behandler svartjenesten for nettjenesten

Husk tidligere at jeg brukte onreadystatechanged-egenskapen til å konfigurere en tilbakeringingsfunksjon. Husk også at tilbakeringingsfunksjonen inneholder en brytersetning som kaller en bestemt funksjon basert på DataSet-navnet. I dette tilfellet er DataSet-navnet vårt CategoriesDS. Derfor kalles processCategory-funksjonen fra tilbakeringingsfunksjonen. La oss ta en titt på denne funksjonen for å se hvordan du bruker XML DOM til å analysere svaret fra nettjenesten.

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

}

}

Husk at getDataFromWS-funksjonen lastet inn XML fra svaret til objXmlDoc-objektet. I processCategory-funksjonen tar jeg xml og analyserer gjennom den for å fylle ut rullegardinlisten Kategori.



Det første jeg gjør, er å opprette et IXMLDOMNodeList-objekt ved hjelp av en del av XML-svaret. DataSet som jeg returnerer fra nettjenesteanropet, returneres som et diffgram, og den eneste delen av det svaret jeg er veldig interessert i, er dataene fra datatabellen som jeg har satt inn i DataSet. Jeg kan få tilgang til dette ved å opprette et IXMLDOMNodeList-objekt fra XML-blokken som inneholder DataTable.



Hvis du ser på koden for nettjenesten, ser du at jeg oppretter en DataTable med navnet Kategorier, og legger den til i DataSet. Når XML-filen returneres fra nettjenesten, er DataSet i en <CategoriesDS>-blokk, og hver rad fra DataTable er i separate <-kategorier>-blokker, som vist i XML-filen nedenfor.

Følgende filer er tilgjengelige for nedlasting fra Microsoft Download Center:Last ned laste GetCategories.xml
ned pakken nå.
Last ned last ned WSXMLHTTP.exe pakken nå.Hvis du vil ha mer informasjon om hvordan du laster ned Microsoft Kundestøtte-filer, kan du klikke følgende artikkelnummer for å vise artikkelen i Microsoft Knowledge Base:

119591 Slik får du Microsoft-støttefiler fra nettbaserte tjenester
Microsoft skannet denne filen for virus. Microsoft brukte den nyeste programvaren for virusgjenkjenning som var tilgjengelig på datoen da filen ble lagt ut. Filen lagres på forbedrede servere med sikkerhet som bidrar til å forhindre uautoriserte endringer i filen.


For å få XML-blokken som inneholder denne DataTable, bruker jeg følgende kode:

objNodeList = objXmlDoc.getElementsByTagName("Categories");

Dette returnerer et IXMLDOMNodeList-objekt som inneholder <kategorier> node. Jeg blar deretter gjennom listen ved hjelp av en løkke.

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

}

Jeg vet allerede at hver <->-node vil ha to noder som jeg trenger: <-ID>-noden og <CategoryName> node. Derfor er det første jeg gjør å opprette en ny IXMLDOMNodeList og fylle den med underordnede noder i den gjeldende <-> noden.

dataNodeList = objNodeList[i].childNodes;

Deretter bruker jeg elementmetoden for å få tilgang til begge nodene som jeg trenger for å fylle ut rullegardinlisten. Den første noden inneholder CategoryID-feltet fra databasen, og den andre noden inneholder CategoryName-feltet fra databasen. Jeg oppretter et nytt Alternativ-objekt, setter teksten til CategoryName, angir verdien til CategoryID og legger det til i rullegardinlisten drpCategory. Koden som brukes i de gjenværende funksjonene, bruker den samme metoden til å hente dataene som kreves fra XML-svaret, og til å fylle ut deler av siden.

NoteSince we're dealing with small amounts of data here, using the DOM is a great way to pull out the data we need. Hvis du har gjort mye data, kan du velge å bruke XSLT i stedet.

Slik får du alt til å fungere

Nå som jeg har dekket små detaljer om hvordan dette fungerer, er det på tide å gå gjennom hvordan du kan bruke de inkluderte eksempelfilene til å se det fungere for deg selv.

Distribuere nettjenesten

Hvis du vil ASP.NET nettjenesten, pakker du ganske enkelt ut det vedlagte nettjenesteeksempelet på roten av nettserveren. Deretter må du åpne koden for DynaProducts.asmx og endre tilkoblingsstrengen. Du må i det minste skrive inn SA-passordet. Når du har gjort denne endringen, kompilerer du nettjenesten på nytt.

Distribuere HTML-filen

HTML-filen inneholder en variabel kalt szUrl som inneholder en nettadresse til nettjenesten. Du finner denne variabelen i funksjonen getDataFromWS nederst i funksjonen. Du må endre dette til nettadressen for nettjenesten du distribuerte ovenfor.


Når du har distribuert både nettjenesten og HTML-filen, går du til HTML-filen. Når den lastes inn, fylles rullegardinlisten Kategori ut av den første XMLHTTP-forespørselen til nettjenesten. Når dette er fylt ut, velger du en kategori for å sette i gang den neste XMLHTTP-forespørselen som fyller ut rullegardinlisten produkter. Hvis du velger et produkt fra rullegardinlisten Produkter, fylles en tabell ut med data om dette produktet.



Legg merke til at siden ikke kommer tilbake under noen av disse XMLHTTP-forespørslene. Det er dette som er fornedringene med XMLHTTP-forespørsler. Hvis jeg hadde gjort dette på en stor side, ville siden også ha beholdt rulleposisjonen uten å "blinke" på brukeren. Hvis du spør meg, er det ganske kraftig!



En ting til: I denne artikkelen brukte jeg XMLHTTP til å spørre en nettjeneste. Jeg kan like enkelt ha brukt det til å lage en forespørsel om en ASPX-side eller en ASP-side. Mulighetene for hvordan du kan bruke denne teknologien, er uendelige. Jeg håper du synes XMLHTTP er nyttig for fremtidig utvikling av nettprogram.

Som alltid kan du sende inn ideer om emner du vil ta opp i fremtidige kolonner eller i Microsoft Knowledge Base ved hjelp av Be om det-skjemaet.

Trenger du mer hjelp?

Vil du ha flere alternativer?

Utforsk abonnementsfordeler, bla gjennom opplæringskurs, finn ut hvordan du sikrer enheten og mer.

Fellesskap hjelper deg med å stille og svare på spørsmål, gi tilbakemelding og høre fra eksperter med stor kunnskap.

Var denne informasjonen nyttig?

Hvor fornøyd er du med språkkvaliteten?
Hva påvirket opplevelsen din?
Når du trykker på Send inn, blir tilbakemeldingen brukt til å forbedre Microsoft-produkter og -tjenester. IT-administratoren kan samle inn disse dataene. Personvernerklæring.

Takk for tilbakemeldingen!

×