Upload
bellini-fadden
View
33
Download
6
Embed Size (px)
DESCRIPTION
Active Server Pages. Dynamic content in Microsoft Internet Information Server 4.0+. Mål. Ha en oversikt over hvordan ASP passer inn i puslespillet Kunne skrive dynamiske sider ved hjelp av ASP Kunne aksessere COM komponenter ved hjelp av ASP - PowerPoint PPT Presentation
Citation preview
Active Server Pages
Dynamic content in Microsoft Internet Information Server 4.0+
Mål
• Ha en oversikt over hvordan ASP passer inn i puslespillet
• Kunne skrive dynamiske sider ved hjelp av ASP
• Kunne aksessere COM komponenter ved hjelp av ASP
• Kunne skrive ATL COM komponenter for bruk med ASP sider
Krav
• ASP kjører på IIS 4.0 og høyere• IIS finnes få Windows NT Server Option Pack• For å bruke XML må en XML parser installeres.
Msxml.dll følger med Internet Explorer 5.0 og høyere
• For å lære ASP bør man ha kjennskap til HTML• JScript/JavaScript eller VBScript kunnskap er også
en fordel, men disse språkene er lette å lære dersom man kan programmere
Hello ASP
<%@ Language="JScript" %>
<html><h1>ASP 1: Hello world</h1>
<% var hello = "Hello ASP" %>
<%=hello%>
</html>
Anatomien til en ASP side
• I utgangspunktet en vanlig HTML side• Elementer som starter med <% angi ASP
elementer• ASP elementer behandles av serveren før
svaret sendes til klienten• ASP elementer er skrevet i et script-språk
som JScript eller VBScript• http://gnats/asp-sample/01hello.asp
Spesielle ASP Elementer
• <%@LANGUAGE er et ASP direktiv som angir hvilket språk (JScript eller VBScript) som skal brukes
• Andre direktiver er f.eks. @CODEPAGE, @TRANSACTION, og @LCID
• <%=...%> er en forkortelse for <% Response.Write(...) %>
Eksempel 2
<%@ Language="JScript" %><html>
<% for ( var i=0; i<10; i++ ) {
var line = "Iteration " + i + "<br>"; Response.Write(line); }%>
</html>
Program-biter
• Vi kan ha programbiter i ASP siden.
• Program-bitene er i et <% %> element.
• Programbitene vil bli utført akkurat som en hvilket som helst script.
• Vi bruker Respose objektets Write metode for å skrive til resultatsiden.
• http://gnats/asp-sample/02-1loop.asp
Html i script i html
<%@ Language="JScript" %><html>
<h1>ASP 2: Looping ASP script</h1>
<% for ( var i=0; i<10; i++ ) { %> <p>Iteration <%=i%>: Hello there</p><% } %>
</html>
Mikse HTML og Script
• Kontrol-flyten fra scriptspråket inkluderer html som er mellom {} etc.
• <%= ... %> fungerer som <% Response.Write(...) %>
• http://gnats/asp-sample/02loop.asp
Scriptobjekter
<%@ Language="JScript" %><html>
<h1>ActiveX Server Pages 3: Time</h1>
The time is <%=new Date()%>.
</body></html>
Script-objekter
• Alle objekter og funksjoner tilgjengelige i scriptspråket er også tilgjengelige i ASP
• I tillegg definerer ASP fem objekter siden kan bruke:– Request – informasjon fra senderen– Response – svaret som vises i browseren– Server – Informasjon og metoder for serveren– Session – inneholder brukers sesjonsinfo– Application – brukes til å dele info mellom brukere
• http://gnats/asp-sample/03time.asp
Forms
<% @Language="JScript" %><html>
<%if( Request.form("inMessagePost")!="true" ){%><!-- html for å vise en form -->
<% } else { %><!-- html for å vise resultatet -->
<% } %>
</html>
Form – oversikt
• Request objektet sendes med når vi mottar en web-side
• Dersom det eksisterer informasjon i en form fra senderen, kan ”form” metoden til Request returnere denne informasjonen
• Vi har laget et skjult element med navn ”inMessagePost” og verdi ”true” som sendes med når brukeren trykker ”post” i formen.
• http://gnats/asp-sample/05form.asp
Form – user entry<form name=”Input Form" method="post" action="05form.asp"><table> <tr><td><b>To:</b></td> <td><input type="text" name="to” value=”recp”/></td></tr> <tr><td><b>From:</b></td> <td><input type="text" name="from” value=”sender”/></td></tr> <tr><td><b>Email:</b></td> <td><input type="text" name="email” value=”[email protected]”/></td></tr> <tr><td><b>Subject:</b></td> <td><input type="text" name="subject” value=”message subject”/></td></tr> <tr><td colspan="2"><b>Message text</b></td></tr> <tr><td colspan="2"> <textarea name="message" rows="6" cols="30">Message Text</textarea> </td></tr> </table>
<input type="hidden" name="inMessagePost" value="true"/> <input type="submit" name="Send message"/> <input type="reset" name="Clear form"/></form>
Form – user input
• Form elementet forteller at vi skal POST’e svaret til 05form.asp (som er samme dokument som formen selv)
• Vi har presentert følgende input-elementer i en tabell:– To, from, email, subject og message
• I tillegg har vi et input element av type ”hidden”. Dette er for å sende med styreparameteren ”inMessagePost”
Form – echo back
<h2>I got the following information:</h2>
<table border=""> <tr><td><b>To:</b></td><td><%=Request.form("to")%></td></tr> <tr><td><b>From:</b></td><td><%=Request.form("from")%></td></tr> <tr><td><b>Email:</b></td><td><%=Request.form("email")%></td></tr> <tr><td> <b>Subject:</b></td><td><%=Request.form("subject")%> </td></tr> <tr><td colspan="2"><b>Message text</b></td></tr> <tr><td colspan="2"> <pre><%=Request.form("message")%></pre> </td></tr></table>
Form – echo back
• Vi bruker Request.Form for å finne verdiene som ble sent til formen.
• Vi bruker <%= ... %> som en snarvei for Response.Write for at det ikke skal bli så mye å skrive og lese.
Forsinkelse
<%@ Language="JScript" %><html><% function f(i) { var result = 1; while ( i > 0 ) result *= i--; return result; }
for ( var i=0; i<10; i++ ) { %> <p>Hello there</p><% f(1000000); // simulate delay } %></html>
Forsinkelse
• Vi definerer en funksjon som gjør mye arbeid for å simulere forsinkelse.
• En og en linje kommer opp når den er ”klar”• Legg også merke til funksjons-deklarasjonen.
Dette er vanlig funksjons-deklarasjon i JScript, og kan også brukes i et ASP script
• http://gnats/asp-sample/06delay.asp
Bruk av COM - ADO<%@ Language="JScript" %><html><% var connection = Server.CreateObject("ADODB.Connection"); connection.Open("guestbook", "admin", ""); var recordset = Server.CreateObject("ADODB.Recordset"); recordset.Open("SELECT * FROM guestbook", connection);
Response.Write("<table border=''>"); for ( recordset.MoveFirst(); !recordset.EOF; recordset.MoveNext() ) { Response.Write("<tr>"); var iter = new Enumerator(recordset.Fields); for ( ; !iter.atEnd(); iter.moveNext() ) { Response.Write("<td>" + iter.item() + "</td>"); } Response.Write("</tr>"); } Response.Write("</table>");%></html>
COM
• Server.CreateObject brukes til å lage et (Inprocess) COM objekt på serveren
• COM Objektet kan aksesseres som fra ethvert script
• Legg merke til at Scriptet har fulle rettigheter, det regnes ikke som et utrygt script
• I JScript bruker vi en Enumerator for å gå gjennom en collection
• http://gnats/asp-sample/07ado.asp
Filsystem
<%@ Language="JScript" %><ul><% var fileSystem = Server.CreateObject("Scripting.FileSystemObject"); var folder = fileSystem.getFolder(Server.MapPath(”."));
var iter = new Enumerator(folder.Files); for ( ; !iter.atEnd(); iter.moveNext() ) { var fileName = iter.item().Name; if ( !fileName.match(".asp$") ) continue;%> <li><a href="<%=fileName%>"><%=fileName%></a></li><% }%></ul>
Filsystem
• Et Scripting.FileSystemObject opprettes på serveren med Server.CreateObject
• Server.MapPath brukes til å få path’en til en virtuell (web) folder. I dette tilfellet returneres ”c:\InetPub\WwwRoot\asp-sample”
• FileSystemObject’s metode getFolder oppretter et Folder objekt
• Scripting.FileSystemObject er en komponent som er designet for å gi skript-språk tilgang til filsystemet.
Filsystem – forts.
• Kun ASP filer skrives ut• Name.match(”.asp$”) bruker JScript string’s
matching metode (regular expressions)• Selve utskriften gjøres med en av-ASP’et linje• Vi bruker et Enumerator objekt for å gå gjennom
Files samlingen på Folder objektet• http://gnats/asp-sample/default.asp
Prosessere XML
<%@ Language="JScript" %><% var xmlFile = (Request.QueryString("xml").Count > 0 ? Request.QueryString("xml") : "Remit-0711-00.xml"); var xslFile = (Request.QueryString("xsl").Count > 0 ? Request.QueryString("xsl") : "PaymentLog-viewer.xsl"); var xml = Server.CreateObject("Microsoft.XMLDOM"); xml.load(Server.MapPath(xmlFile));
var xsl = Server.CreateObject("Microsoft.XMLDOM"); xsl.load(Server.MapPath(xslFile));
var html = xml.transformNode(xsl);
Response.Write(html);%>
Prosessere XML
• QueryString henter ut argumenter gitt til URL’en til web-siden (f.eks. ”.../09Xml.asp?xml=Remit-0817-00.xml”)
• transformNode gjør hele arbeidet med å transformere xml-en til html ved hjelp av stylesheet’et
• Det eksisterer en mengde andre funksjoner på Microsoft.XMLDOM objektet.– http://gnats/asp-sample/09Xml.asp– http://gnats/asp-sample/09Xml.asp?xml=Remit-0817-00.xml– http://gnats/asp-sample/09Xml.asp?xsl=PaymentLog-Viewer2.xsl
ATL og ASP
COM komponenter for bruk i ASP sider
C++ COM ASP
• En ASP side kan aksessere ethvert objekt som implementerer IDispatch interfacet
• Aksessen skjer på samme måte som enhver script-basert aksess til en komponent
• Metoder som ikke er ”oleautomation” kompatible kan ikke kalles
• Det ser ut som om script-interpreteren ikke støtte VARIANT-records (ennå?)
Hello ATL - IDLimport "oaidl.idl";import "ocidl.idl";
[ object, uuid(B6207922-7993-11D4-A235-0008C785A717), dual, pointer_default(unique) ]
interface ICaseTransform : IDispatch { HRESULT ToUpperCase([in] BSTR input, [out,retval] BSTR* upcase);};
[ uuid(4F63DF31-78E1-11D4-A234-0008C785A717), version(1.0) ]library ASPCOMPONENTLib{
importlib("stdole32.tlb");importlib("stdole2.tlb");
[ uuid(B6207923-7993-11D4-A235-0008C785A717) ]coclass CaseTransform {
[default] interface ICaseTransform;};
};
Hello ATL - Headerclass ATL_NO_VTABLE CoCaseTransform :
public CComObjectRoot,public CComCoClass<CoCaseTransform, &CLSID_CaseTransform>,public IDispatchImpl<ICaseTransform, ...>
{public:DECLARE_REGISTRY_RESOURCEID(IDR_CASETRANSFORM)
// ProgId ASPComponent.CaseTransform.1// Clsid {B6207923-7993-11D4-A235-0008C785A717}
BEGIN_COM_MAP(CoCaseTransform)COM_INTERFACE_ENTRY(ICaseTransform)COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
STDMETHOD(ToUpperCase)(BSTR input, BSTR* upcaseString) { CComBSTR result(input); wcsupr(result); *upcase = result.Detach(); return S_OK; }};
Hello ATL - ASP
<%@ LANGUAGE="JScript" %><HTML>
<% var component = Server.CreateObject("ASPComponent.CaseTransform"); Response.Write(component.ToUpperCase("hello world"));%>
</HTML>
Hello ASP
• ASP scriptet bruker Server.CreateObject for å opprette det nye objektet
• Scriptet bruker ProgId for å angi hvilket objekt som skal opprettes (husk å registrere dll’en)
• Merk at IIS 4.0 kun støttet InProcess komponenter (dette kan påvirkes)
• IIS tar lock på dll’en. Denne locken blir ikke frigjort før serveren rebootes (?!?)
• http://gnats/asp-sample/10AspComponentTest.asp
ATL – Bruk av ASP objekter
• Når et objekt opprettes på en side, vil metodene ”OnStartPage” og ”OnEndPage” kalles, dersom objektet implementerer dem
• OnStartPage – kalles når objektet opprettes, gir komponenten tilgang til ASP’s objektmodell
• OnEndPage – kalles når siden er ferdig presentert. Etter at OnEndPage er kalt, vil objektene fra OnStartPage være ugyldige
Eksempel
• OnStartPage – setter opp alle objekt-referansene vi trenger
• OnEndPage – slipper alle objektreferanser• OutputPage – skriver ut en web-side ved å bruke
Response objektet• OutputPage er funksjonelt lik eksempel 5, som
bruker Forms• http://gnats/asp-sample/11AspSecondComponten
t.asp
OnStartPage
STDMETHODIMP CoAspTestComponent::OnStartPage (IUnknown* pUnk) {
CComPtr<IScriptingContext> pContext;HRESULT hr = pUnk->QueryInterface(IID_IScriptingContext, (void **)&pContext);
// Get all the scripting object referencesif ( SUCCEEDED(hr) ) hr = pContext->get_Request(&m_pRequest);if ( SUCCEEDED(hr) ) hr = pContext->get_Response(&m_pResponse);if ( SUCCEEDED(hr) ) hr = pContext->get_Server(&m_pServer);if ( SUCCEEDED(hr) ) hr = pContext->get_Session(&m_pSession);if ( SUCCEEDED(hr) ) hr = pContext->get_Application(&m_pApplication);
if ( FAILED(hr) )// Release all object references if something went wrong
return S_OK;}
OnEndPage
STDMETHODIMP CoAspTestComponent::OnEndPage () {
// Release all interfacesm_pRequest.Release();m_pResponse.Release();m_pServer.Release();m_pSession.Release();m_pApplication.Release();
return S_OK;}
OutputPage
STDMETHODIMP CoAspTestComponent::OutputPage(){
CComPtr<IRequestDictionary> pForm;m_pRequest->get_Form(&pForm);
int formCount = 0;pForm->get_Count(&formCount);
if ( formCount == 0 ) { // means no post actionreturn OutputFormPage();
} else {return OutputResultPage(pForm);
}}
OutputFormPageHRESULT CoAspTestComponent::OutputFormPage(){
CComVariant vFormPage(L"<form method='post' action='11AspSecondCompontent.asp'>\n" L"<h2>Please insert your message</h2>\n" L"<table>\n" L"<tr><td><b>To:</b></td>”
L”<td><input type='text' name='to' value='recp'/></td></tr>\n" L"<tr><td><b>From:</b></td>”
L”<td><input type='text' name='from' value='sender'/></td></tr>\n" L"<tr><td colspan='2'><b>Message text</b></td></tr>\n”
// OSV L"</table>\n" L"<input type='submit' name='Send message'/>\n" L"<input type='reset' name='Clear form'/>\n"L"</form>");
return m_pResponse->Write(vFormPage);}
OutputResultPageHRESULT CoAspTestComponent::OutputResultPage(IRequestDictionary* pForm){
m_pResponse->Write(CComVariant(L"<h2>I got the following information:</h2>\n"));
m_pResponse->Write(CComVariant(L"<table border=''>\n"));
CComVariant fields[] = { L"to", L"from", L"email", L"subject" };for ( int i=0; i<sizeof(fields)/sizeof(*fields); i++ )
OutputFieldValue(fields[i]);
m_pResponse->Write(CComVariant(L"<tr><td colspan='2'><b>Message text</b></td></tr>\n"
L"<tr><td colspan='2'><pre>"));CComVariant fieldValue;pForm->get_Item(CComVariant(L"message"), &fieldValue);m_pResponse->Write(fieldValue);m_pResponse->Write(CComVariant(L"</pre></td></tr>\n</table>\n"));
return hr;}
OutputFieldValue
HRESULT CoAspTestComponent::OutputFieldValue(IRequestDictionary* pForm, CComVariant fieldName)
{CComVariant fieldValue;
pForm->get_Item(fieldName, &fieldValue);m_pResponse->Write(CComVariant(L"<tr><td><b>"));m_pResponse->Write(fieldName);m_pResponse->Write(CComVariant(L":</b></td><td>"));m_pResponse->Write(fieldValue);m_pResponse->Write(CComVariant(L"</td></tr>"));
return hr;}
Grenser for hva som kan gjøres
• På grunn av locking av dll er det vanskelig å bytte ut en dll
• Jeg har ikke forsøkt å bruke debuggeren mot et ASP script, men jeg tror det er vrient
• ASP kan ikke aksesser IUnknown komponenter eller Variant structer
• Konklusjon: ASP egner seg best som et tynt presentasjonslag over eksisterende funksjonalitet
ASP og IUnknown
• http://gnats/asp-sample/12-1AspStructs.asp
• Det går ikke å aksessere funksjoner som ikke er oleauto.
• Eksempelet viser aksess av :
HRESULT GetStruct([out, retval, ref] struct MyTestStruct** theStruct);
ASP og Variant Records
• http://gnats/asp-sample/12-2AspStructs.asp
• Eksempelet viser kall på en metode som returnerer en struct i en VARIANT
Structwrapper
• Det er relativt enkelt å skrive en wrapper for structs i en IDispatch interface
• Bruken av denne wrapperen er nesten transparent fra Script klienter
• Dessverre ser det ut som om dette fremprovoserer en feil i script interpreter (?)
• Bruk vil få serveren til å bruke mer og mer ressurser på ”inetinfo.exe” prosessen inntil maskinen krasjer.
• Bruk vil også blokke alle andre web-requester
Eksempler
• Jeg skal gjøre tilgjengelig en samling med ASP script (eksemplene her) og et VC 6.0 prosjekt med ATL ASP-kode
• ATL koden inkluderer scriptwrapper. Det går fint ann å leke med den, men man må reboote serveren etterpå ;-)
Hva nå?
• Både JScript, og ASP er dokumentert i MSDN• Scriptspråk
– JScript - msdn.microsoft.com/scripting/jscript/– VBScript - msdn.microsoft.com/scripting/vbscript/– Generelt – http://msdn.microsoft.com/scripting/– Se spesielt Language Reference
• http://msdn.microsoft.com/workshop/server/• http://msdn.microsoft.com/workshop/server/asp/
ASPover.asp
MSDN
• For orden skyld: Her er plasseringen i MSDN• ASP Object Model:
– Platform SDK/Web Services/Internet Information Services SDK/Active Server Pages Guide/Visual Basic Object Model
• Jscript– Plaform SDK/Tools and Languages/Scripting/Jscript
• VBScript– Plaform SDK/Tools and Languages/Scripting/Vbscript