Modi per modulare i blocchi di codice in ASP Classic

4

Ho un file.asp enorme con tutti i miei report. Ho modularizzato la pagina usando querystring, quindi crea molte "pagine virtuali" con Report # 1, Report # 2 e così via.

Ho alcuni blocchi di codice che uso più di una volta nella pagina. In realtà sto ripetendo il codice, ma ho già iniziato a usare Function per, ad esempio, formattare la data. Ma il blocco di codici è simile a pannelli con alcune selezioni in database, tabelle e così via ... Voglio dire, un pannello può avere più di 200 linee di codice.

Vorrei creare un qualche tipo di funzione per riutilizzare il codice, invece di replicarlo ogni volta. Con asp classico, quante opzioni ho? Uno che ho scartato è creare un file asp per pannello e in un file master includere il pannello dove è necessario. Sono davvero fuori da questo approccio. La funzione è l'approccio migliore?

    
posta Khrys 10.07.2014 - 14:46
fonte

2 risposte

4

Ero l'unico autore di un'applicazione ASP di classe molto grande per quasi un decennio. C'erano diverse cose che ho imparato lungo la strada che miglioravano la qualità del codice e la velocità con cui potevo sputarlo molto.

Prima di tutto, invece di riscrivere il codice più e più volte, crea una semplice funzione che faccia il lavoro pesante. Sembra che tu lo stia già facendo. Ciò consente di scrivere il codice più velocemente con meno errori, ma consente anche di modificare il comportamento o il look-and-feel dell'intera applicazione modificando alcune righe di codice. Il mio obiettivo era di posizionare qualsiasi cosa che fosse mai ripetuta in una funzione.

In secondo luogo, quando ho capito che, sì, ASP classico supporta le classi. Invece di scrivere codice HTML e codice per ognuno dei tanti rapporti, ho creato una classe di report che racchiudeva le funzionalità di cui avevo bisogno. Quindi tutto ciò che dovevo fare era passare un set di record alla classe e il rapporto sarebbe stato generato con un paio di righe di codice. Se stavo visualizzando molte tabelle e in seguito volevo rendere ordinabili le righe facendo clic sull'intestazione di una colonna, era una cosa banale estendere questa funzionalità all'intera applicazione modificando una singola classe.

Ecco alcune cose che ho trasformato in classi:

  • Tabelle che mostravano set di record
  • Modulo per modificare i record del database
  • Query di database (non ho mai scritto di nuovo SQL inline di nuovo)
  • Record set in modo da poterli convertire in tabelle e altri tipi di visualizzazione

L'ultima cosa che ho fatto che ha sostanzialmente migliorato la qualità dell'applicazione è stata abbandonare completamente su ASP. Penso che "Non ho davvero bisogno di un IDE", "Debugging with print statements è abbastanza buono". Quanto ero sbagliato. Ora che ho passato a C # e MVC non potrei mai immaginare di tornare al classico ASP.

    
risposta data 10.07.2014 - 15:12
fonte
1

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.

    
risposta data 27.09.2017 - 10:29
fonte

Leggi altre domande sui tag