L'ASP classico può essere scritto totalmente modulare utilizzando gli script di script AKA (Windows Script Components).
Questi sono file, scritti in VBscript o Jscript, che hanno proprietà e metodi definiti, e in questo modo possono essere usati proprio come i componenti COM. Il vantaggio è che non devi registrarli o riavviare IIS dopo aver cambiato il codice all'interno di essi.
Questo è un esempio di WSC (si noti che questo non è stato verificato, non è completamente funzionale e potrebbe contenere errori). Copia-incolla questo codice nel tuo sito ASP da qualche parte e chiamalo debugging.wsc:
<?xml version="1.0"?>
<component>
<?component error="true" debug="true"?>
<registration
description="debugging"
progid="debugging.WSC"
version="1.00"
classid="{AE434F7F-C64E-46D4-A103-FF3D47B05A91}"
>
</registration>
<public>
<!-- PROPERTIES -->
<property name="executionTime">
<get/>
</property>
<property name="logpath">
<get/>
<put/>
</property>
<!-- METHODS / PUBLIC FUNCTIONS -->
<method name="log">
<PARAMETER name="inputValue"/>
</method>
<method name="send_mail">
<PARAMETER name="who"/>
<PARAMETER name="subject"/>
<PARAMETER name="message"/>
</method>
<method name="hellofromjscript">
<PARAMETER name="name"/>
</method>
<method name="getPersonByName">
<PARAMETER name="name"/>
</method>
<method name="open"></method>
<method name="close"></method>
</public>
<implements type="ASP" id="ASP"/>
<script language="VBScript">
<![CDATA[
' here is where global variables go
' every property has a corresponding global varibale
dim executionTime, logpath
dim fs, WriteFile
' start a timer every time this component is loaded
' this way we can debug the running time at various places in the ASP page
dim timeStart : timeStart = Timer()
'getters and setters for the properties'
function get_executionTime()
get_executionTime = FormatNumber((Timer()-timeStart),4,,,0)
end function
function get_logpath()
get_logpath = logpath
end function
function put_logpath(newValue)
logpath = newValue
end function
' *************************************************
' * PUBLIC FUNCTIONS *
' *************************************************
function log(message)
' make sure the path you are logging to has 'modify' rights for the user of the current application pool in IIS
' determine path to the log file
dim LOG_FILEPATH : LOG_FILEPATH = logpath & year(date)
if month(date) < 10 then
LOG_FILEPATH = LOG_FILEPATH & "0" & month(date)
else
LOG_FILEPATH = LOG_FILEPATH & month(date)
end if
LOG_FILEPATH = LOG_FILEPATH & filename & ".log"
' create the file if it doesn't exist
If NOT fs.FileExists(LOG_FILEPATH) Then
call fs.OpenTextFile(LOG_FILEPATH, 2, True, 0)
Set WriteFile = fs.OpenTextFile(LOG_FILEPATH, 2, True, 0)
call WriteFile.WriteLine("Logfile Created " & currentDateTime)
WriteFile.Close()
Set WriteFile = Nothing
End If
' write the log line
Set WriteFile = fs.OpenTextFile(LOG_FILEPATH, 8, True, 0)
call WriteFile.WriteLine(message)
WriteFile.Close()
Set WriteFile = Nothing
end function
function send_mail(who,subject,message)
' *******************************************************************'
' * E-MAIL A MESSAGE *'
' *******************************************************************'
' You need some variables in the application scope to use this method
' A WSC can access the standard ASP objects like server, request, application, session etc.
' because we included the <implements type="ASP" id="ASP"/> tag at the top.
if hasValue(who) Then
Dim myMail
Set myMail = CreateObject("CDO.Message")
myMail.Subject = subject
myMail.From = application.contents("DefaultEmailSender")
myMail.To = who & " <" & who & ">"
myMail.TextBody = message
myMail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
myMail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = Application.contents("MailServer")
myMail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
myMail.Configuration.Fields.Update
myMail.Send
set myMail = nothing
end if
End Function
function getPersonByName(name)
' It is also possible to return an object from a WSC
' just SET it in the return value and also SET it in the code that calls the function:
' Please note that this function not functional, just an example of what can be accomplished.
sqlstatement = "DECLARE " &_
"@username varchar(50) " &_
"SELECT " &_
"@username = " & parameter.string(name) & " "
' parameter could be a WSC that parses user inputs and makes sure the application is protected
' against SQL injection attacks
sqlstatement = sqlstatement & "SELECT * "
sqlstatement = sqlstatement & "FROM Users "
sqlstatement = sqlstatement & "WHERE username = @username "
' DataAccessLayer could be another WSC that handles database connections and logs queries for example
set getPersonByName = DataAccessLayer.select(sqlstatement)
end function
' just an internal helper function.
' because it is not defined in the XML part at the top, this function can only be used internally
function hasValue(Val)
hasValue = NOT(isNull(Val) OR Val="")
end function
'standard methods for opening and closing more objects - these can be extra WSC's as well'
function open()
Set fs = CreateObject("Scripting.FileSystemObject")
logpath = Server.Mappath("/") & "\logs\"
end function
function close()
Set fs = Nothing
end function
]]>
</script>
<script language="javascript">
<![CDATA[
function hellofromjscript(name){
// Jscript works aswell. Keep in mind that Jscript is case-sensitive and
// that you will need to address the full ASP object, I.E. Application.Contents("myvar") instead of just Application("myvar")
Response.Write("Hello " + name);
};
]]>
</script>
</component>
Un WSC può essere usato da ASP come questo (a condizione che tu abbia il WSC in una directory chiamata wscs ):
<%
dim debugging, recordset
Set debugging = GetObject("script:"&Server.MapPath("/wscs/debugging.wsc"))
debugging.open()
debugging.log("Hello from a WSC")
' you can return objects like recordsets from a WSC:
set recordset = getPersonByName("bill")
set recordset = Nothing
debugging.close()
Set debugging = Nothing
%>
Utilizzando WSC è possibile caricare le funzionalità in modo condizionale (a differenza dei file include, che sono sempre inclusi).
È possibile programmare utilizzando le regole N-tier, poiché i WSC possono caricare altri WSC.