18
Tags:
visual-basic
Skrevet af
Bruger #4055
@ 18.07.2003
Vil du gerne kunne lave dine egne serverkomponenter til brug i ASP? Ved hjælp af Microsoft Visual Basic kan det nemt lade sig gøre.
Jeg forudsætter at du kan programmere VB-kode (f.eks. ligesom du gør i ASP/VBscript), har Microsoft Visual Basic 6.0 og et minimum af kendskab til brug af serverkomponenter i ASP.
Introduktion
En komponent består af en eller flere klasser. En klasse indeholder egenskaber (properties, variabler) og metoder (funktioner, subrutiner) og har også mulighed for at indeholde underobjekter, hvilket dog rent programmeringsmæssigt minder om en objektegenskab. Ud fra en klasse kan man lave et objekt og med dette objekt kan man ændre i objektets egenskaber og kalde dets metoder.
I denne artikkel vil jeg vise hvordan man laver en komponent som også kan bruges til noget. I stedet for blot at lave en der udskriver Hello World eller lignende, vil jeg vise, hvordan du laver en komponent du kan bruge til at udskrive recordsets fra en databaseforespørgsel. Koden kunne selvfølgelig blot have været lavet direkte i ASP, men nu skal du jo lære at lave en komponent, så lad os starte.
Først starter du Microsoft Visual Basic 6.0. Når det er gjort skulle der gerne være fremkommet en boks, hvor du kan vælge hvilken type projekt du vil oprette:
Her vælger man ActiveX DLL. Nu åbner Visual Basic et nyt projekt til dig, hvor du kan lave en ActiveX DLL, som er det en serverkomponent skal være.
Det første man bør gøre er at sætte navn på klassen og projektet. Du finder Project-vinduet (normalt øverst til højre) og vælger Project1. I Properties-vinduet (normal lige nedenunder) skriver du navnet på projektet. Skriv her MyComponent. Dernest vælger du Class1 og ændrer navnet til RecordSetOutput. Du kan se i Properties-vinduet at der også er en property, der hedder Instancing, som gerne skulle stå til 5 - MultiUse. Hvis man laver mere avancerede serverkomponenter, hvor dine klasser benytter sig af andre interne klasser, skal disse interne klasser have sat Instancing til 1 - Private, da de så kun kan benyttes internt - og ikke af ASP-koden, når komponenten er færdig.
I midten har man kode-vinduet. Det er sandsynligvist tomt, men måske står der Option Explicit. Hvis der ikke står dette kan du med god grund skrive dette øverst. Dette får Visual Basic til at tjekke at alle variabler er deklærede og hjælper en stor del af fejlfindingen i større projekter.
Serverkomponenten MyComponent.RecordSetOutput
Som du sikkert ved oprettes et objekt fra en komponent i ASP ved at skrive:
Set obj = Server.CreateObject("ComponentName.ClassName")
På den måde vi har navngivet vores projekt og klasse, opretter du altså et objekt med strengen "MyComponent.RecordSetOutput"
Den komponent du skal til at lave skal, som navnet siger, kunne vise et recordset. Til dette skal der bruges følgende egenskaber og metoder:
- Egenskab:
RowCode - Indeholder HTML-koden der skal vises for en række i recordsettet.
- Egenskab:
SplitCode - Indeholder HTML-koden der skal vises imellem hver række der bliver udskrevet.
- Egenskab:
EmptyCode - Indeholder HTML-koden der skal vises, hvis recordsettet er tomt.
- Metode:
GetListCode - Funktion der modtager et recordset og returnerer HTML-koden der viser dette recordset.
- Metode:
OutputList - Subrutine der modtager et recordset, kalder GetListCode og udskriver HTML-koden vha. Response.Write fra ASP.
Det skal lige siges at RowCode indeholder HTML-kode. For at vise en bestemt felt fra recordsettet skrives det ind som et HTML-tag, f.eks. <username> vil udskrive username fra recordsettet.
Hele koden er som følger. Læs den godt igennem - også kommentarerne. Så burde du forstå den.
Option Explicit
' Egenskaber:
Public RowCode As String
Public SplitCode As String
Public EmptyCode As String
' Funktioner:
Public Function GetListCode(ByRef rs As Variant) As String
' rs indeholder her det recordset, funktionen skal returnere koden for
On Error Resume Next ' Bryd ikke ned ved fejl
Dim Output As String ' Denne variabel "udskriver" vi til
Output = ""
If rs.EOF And rs.BOF Then ' Er recordsettet tomt?
Output = Output & EmptyCode ' Udskriv koden for en tom liste
Else
Dim Row As String ' Indeholder koden for en række
Dim Felt As Variant ' Indeholder feltnavn
Dim Data As Variant ' Indeholder data
Dim i As Integer
rs.MoveFirst ' Gå til første række i recordsettet
While Not rs.EOF ' Kør igennem alle rækker i recordsettet
If Output <> "" Then ' Har vi været gennem første udskrift?
Output = Output & SplitCode ' Tilføj split-koden
End If
Row = RowCode ' Sæt row til den kode der er angivet i RowCode
' Nu skal felterne <felt> udskiftes med den tilsvarende data:
For i = 0 To rs.Fields.Count - 1 ' Gennemløb alle felter
Felt = rs.Fields(i).Name ' Få navnet på felt nr. i
Data = "" ' Hvis næste linie fejler vil Data indeholde ""
Data = CStr(rs(Felt)) ' Hent feltet og konverter til streng
Row = Replace(Row, "<" & Felt & ">", Data) ' Indsæt feltet
Next i
Output = Output & Row ' Tilføj rækken til outputtet
rs.MoveNext ' Gå til næste række i recordsettet
Wend
End If
GetListCode = Output ' Returner outputtet (til ASP-scriptet)
Err.Clear ' Fjern fejl-markering, hvis der har opstået fejl i scriptet
End Function
' Subrutiner:
Public Sub OutputList(ByRef rs As Variant)
' rs indeholder her det recordset, subrutinen skal vise
On Error Resume Next ' Bryd ikke ned ved fejl
Dim oc As ObjectContext ' Opret en variabel til vores ASP ObjectContext
Dim Code As String
Code = GetListCode(rs) ' Få koden vha. vores funktion
Set oc = GetObjectContext() ' Få fat i ASP-sidens ObjectContext
oc("Response").Write Code ' Udfør Response.Write - ligesom i ASP
Err.Clear ' Fjern fejl-markering, hvis der har opstået fejl i scriptet
End Sub
Ved første øjekast er man måske forvirret. Men ser man nærmere efter er det samme kode som man skriver i ASP/VBScript, dog med enkelte undtagelser. En af de vigtigste undtagelser er at man kan definere hvad variablerne kan indeholde. F.eks. kan man definere en variabel ved: Dim MyVar As String. Dette opretter en variabel MyVar som indeholder en streng. Det er ikke ligesom i ASP-kode, hvor variabler er såkaldte Variants - der kan indeholde en hvilken som helst data. Man kan også bruge Variants i Visual Basic, men det er ikke klogt at gøre det med mindre der ikke er andre muligheder, da det kører noget mere langsomt en variabler, der er fast definerede. En anden mindre forskel fra ovenstående kode og ASP/VBScript er at man kan skrive variabelnavnet efter Next - f.eks. For i = 1 To 10: Next i
Man bør lægge mærke til at koden Public er brugt foran egenskaberne, funktionen og subrutinen. Dette gør at de kan "ses" fra ASP-scriptet man bruger komponenten i. Ellers kan man bruge koden Private, der gør at funktionen, subrutinen eller variablen kun kan bruges internt i klassen.
Den sidste ting du skal gøre før projektet er færdigt er at gå ind i menuen Project -> References ... -> Finde henholdsvis "Microsoft Active Server Pages Object Library" og "COM+ Services Type Library" og klikke dem på. Hvis der er flere der hedder det samme skal man blot klikke én af dem på. Disse såkaldte referencer gør at komponenten kan få fat i ASPens ObjectContext og derved kan benytte sig af Response.Write, som er tilfældet i subrutinen.
Når koden er skrevet ind og referencerne er sat kan man gemme projektet.
Nu skal projektet kompileres til en .dll-fil, som efterfølgende registreres, så den kan bruges i dine ASP-scripts.
Vælg File -> Make MyComponent.dll ... -> Gem .dll-filen et godt sted, som ikke er beskyttet (gem den f.eks. ikke under dit eget skrivebord eller dokument-mappe). Et godt sted er Windows\\System32-mappen.
Nu hvor .dll-filen er lavet kan du registrere .dll-filen som komponent. Det gør du ved at gå ned i Start-menuen -> Kør... ->
Skriv: regsvr32 "filsti" - hvor filsti er stien på .dll-filen. F.eks. C:\\Windows\\System32\\MyComponent.dll -> Tryk Ok. Nu fremkommer en boks, hvor der stod at alt gik godt. Tryk blot Ok.
Den første test af komponenten
Nu bliver det spændende. Vores første testforsøg af komponenten. Opret først en database, der indeholder en tabel med felterne username og email. Indtast nogle data i tabellen. Opret en .asp-fil og indskriv følgende kode:
<%
' Sæt selv ConnStr og evt. SQL til passende indstillinger:
ConnStr = "---"
SQL = "SELECT username, email FROM users"
Set db = Server.CreateObject("ADODB.Connection") ' Opret databaseobjekt
db.Open ConnStr ' Åben en databaseforbindelse
Set rs = db.Execute(SQL) ' Få en liste over brugere
Set pl = Server.CreateObject("MyComponent.RecordSetOutput") ' Opret objekt
' Udskriv bruger samt hans e-mail-adresse:
pl.RowCode = "<username>: <a href=""mailto:<email>""><email></a>"
pl.SplitCode = "<br>" & vbCrLf ' Lav linieskift mellem hver bruger
pl.EmptyCode = "Ingen brugere." ' Udskriv hvis recordsettet er tomt
Response.Write pl.GetListCode(rs) ' Udskriv listen vha. ASP
Response.Write "<hr>" ' Vis vandret streg
pl.OutputList rs ' Udskriv listen vha. vores komponent
' Ryd op - luk databaseforbindelse og slet objekter:
rs.Close
db.Close
Set pl = Nothing
Set rs = Nothing
Set db = Nothing
%>
Gå ind og se .asp-dokumentet og se udskriften af brugere. Der skulle gerne være to udskrifter adskilt af en vandret streg. Den første udskrift er lavet vha. selve ASP-scriptet, der brugte Response.Write til at vise koden den modtog fra funktionen i vores komponent. Den anden udskrift er lavet direkte fra vores komponent - i subrutinen. Her henter komponenten det såkaldte ObjectContext, som er standard-objekterne i ASP: Response, Request, Session, Application, etc. Dem du hele tiden benytter dig af.
Udvikling af serverkomponenter
Nu kan du så småt gå i gang med at udvikle dine egne serverkomponenter. Start evt. simpelt med at udskrive forskellige variabler og bruge ASP ObjectContext som Response, Request o.l. Du kan f.eks. også læse min artikel om klasser, hvilket vil hjælpe dig til at udvikle mere avancerede serverkomponenter - måske i stil med dem man kan købe af billed-komponenter, upload-komponenter, e-mail-komponenter, etc.
En komponent som ADODB har flere klasser. F.eks. er der ADODB.Connection, RecordSet, Stream, m.fl. Disse er blot klasser i den samme komponent. Du kan tilføje flere klasser til dit projekt ved vælge menuen Project -> Add Class Module -> Class Module. En smart ting er at en funktion kan returnere et objekt. Dette kan man f.eks. se i ADODB-komponenten flere steder. Et oplagt eksempel er funktionen Execute, som man bruger til at køre SQL-kode, der returnerer et ADODB.RecordSet-objekt.
Har du fået mod på at udvikle dine egne serverkomponenter er det bare med at komme igang. Selvfølgelig skal man have adgang til serveren før det kan lade sig gøre. Hvis man har et webhotel kan man evt. spørge hoteludbyderen om han vil lægge komponenten ind. Det vil mange, hvis de blot får kildekoden for at se at du ikke prøver at hacke deres server.
Sidst vil jeg nævne hvordan man unregistrer sin komponent for at kunne kompilere en ny version. Det er nemlig sådan at en regisreret .dll-fil bliver åbnet - og så kan den ikke overskrives. Når man sidder og udvikler serverkomponenter finder man sandsynligvis ofte fejl, retter dem og skal kompilere .dll-filen igen. For at overskrive den gamle .dll-fil unregistrer du den ved: Start-menuen -> Kør... -> Skriv: regsvr32 -u "filsti" - hvor filsti igen er stien på .dll-filen. Hvis du stadig ikke kan overskrive den, prøv da at åbne Windows Jobliste (Ctrl + Alt + Del) -> Vælg fanen Processer -> Find inetinfo.exe -> Afslut denne og prøv så at kompilere din .dll-fil igen. Inetinfo.exe er Internet Information Server, som måske har låst din .dll-fil. Når du afslutter denne bliver adgangen til .dll-filen låst op og Internet Information Server starter sig selv op igen. Det er måske i længden besværligt hele tiden at regisrere/unregistre sin .dll-fil for at fejlrette på sin komponent, men jeg har endnu ikke fundet nogen nemmere løsning. Hvis du kender til det, må du meget gerne kontakte mig og fortælle mig om det.
Konklusion
Hvis man har fået smag for at udvikle sine egne serverkomponenter er det bare med at komme igang. De er muligheden for ASP til at få adgang til alt hvad du måtte ønske. Derudover er de også gode til bl.a. trivielle opgaver som også kunne være lavet i ASP, da de er kompilerede som .dll-filer og derved kører mange gange hurtigere end et ASP-script.
Hvad synes du om denne artikel? Giv din mening til kende ved at stemme via pilene til venstre og/eller lægge en kommentar herunder.
Del også gerne artiklen med dine Facebook venner:
Kommentarer (3)
Hey Bjarke
Når nu du er så godt igang med ActiveX ville det være en god ide at stile din kode mere i retningen af OOP f.eks lave function's til åbning/lukning af database og recordset på den måde blivet livet meget lettere :o)
Men ellers er det en god artikel du har skrevet simpel og let at gennemskue ;o)
/Websam
meget spøndende... sejt
meget spændende... sejt
Du skal være
logget ind for at skrive en kommentar.