Q & A

Questo spazio è dedicato alla risoluzione dei vostri problemi di programmazione. Proponete domande tecniche ed otterete risposte pratiche ed esaustive ai vostri questi.

q&a@infomedia.it

 

CLI e CLR: qual’è la differenza?

Studiando la documentazione del .NET Framework mi imbatto spesso nelle sigle CLI e CLR: sono sinonimi del runtime .NET? Se sì, perché usare due termini differenti?

Gianfranco

Risponde Alberto Falossi

La Common Language Infrastructure (CLI) è un sottoinsieme delle funzionalità del Common Language Runtime (CLR). La CLI comprende l’Execution Engine e una parte della libreria della classi (tipi base, Reflection, XML): come si può intuire definisce i componenti essenziali per l’esecuzione di applicazioni .NET. Il CLR è l’implementazione della CLI sotto Windows con l’aggiunta di alcune componenti come ADO.NET, ASP.NET e Windows Forms.
Recentemente Microsoft ha commissionato a Corel il porting della CLI sotto Linux e presto (probabilmente nel primo trimestre 2002) sarà disponibile l’implementazione di .NET per un sistema operativo diverso da Windows.


Upload di file con ASP

Sto facendo l'upload di alcune file grafici da client utilizzando un database Access: vorrei salvare l'immagine in una directory del mio server web (e fin qui non ci sono problemi) e salvare il path e relativa descrizione nel database per poi richiamarli tramite ASP nel momento della visualizzazione.
Riesco a salvare correttamente l’immagine nella directory del mio web server, ma non riesco a salvare il path e descrizione dell'immagine nel database. Cosa posso fare?
Grazie per qualsiasi aiuto!

Antonio

Risponde Andrea Chiarelli

Ciao Antonio,
nel tuo messaggio non indichi il componente che utilizzi sul server per gestire l'upload né indichi le difficoltà che incontri per il salvataggio dei dati nel database. In ogni caso, immagino che la descrizione dell'immagine e il nome del file venga data dall'utente in uno dei campi della form di upload mentre l'informazione sul path di memorizzazione del file d'immagine sul server lo decidi tu. Supponendo che tu sia in questa situazione e che utilizzi Posting Acceptor come componente per l'upload, dovresti creare un recordset a partire dal tuo database e memorizzare le informazioni come nel seguente esempio:

<%
'Recupero delle informazioni sul file di immagine
Dim NomeFile: NomeFile = Request.Form("FileName")
Dim Estensione: Estensione = Request.Form("FileExtension")
Dim Descrizione: Descrizione = Request.Form("Descrizione")

'Creazione del recordset e salvataggio delle informazioni
Dim rs: Set rs = Server.CreateObject("ADODB.Recordset")
rs.ActiveConnection = "Provider=Microsoft.Jet.OLEDB.4.0;DataSource=c:\db\mydb.mdb"
rs.LockType = 3                        'adLockOptimistic
rs.Open "SELECT * FROM Immagini"

rs.AddNew

rs("codice") = 1
rs("path") = "immagini/" & Left(NomeFile, Instr(NomeFile, ",") -1) & Estensione
rs("descrizione") = Descrizione

rs.Update
rs.Close: Set rs = Nothing
%>

Posting Acceptor aggiunge automaticamente alla collection Form dell'oggetto Request i seguenti elementi: FileName, FilePath, FileSize, FileExtension. In particolare FileName conterrà una stringa del tipo: "immagine, c:\percorso_del_client\immagine.gif", da cui la necessità di estrarre in modo un po' articolato il nome del file d'immagine.
Naturalmente se usi un componente diverso per l'upload dovrai consultare la relativa documentazione per capire come accedere alle informazioni che ti servono, ma in linea di massima credo che dovresti soltanto modificare le prime tre istruzioni di assegnamento.
A questo punto per la visualizzazione dell'immagine dovresti scrivere del codice analogo al seguente:

<%
Dim rs: Set rs = Server.CreateObject("ADODB.Recordset")
rs.ActiveConnection = "Provider=Microsoft.Jet.OLEDB.4.0;DataSource=c:\db\mydb.mdb"
rs.Open "SELECT * FROM Immagini WHERE codice = 1"

Response.Write "<IMG SRC='" & rs("path") & "'><BR>"
Response.Write rs("descrizione")

rs.Close: Set rs = Nothing
%>


La classe System.Convert

Spettabile redazione,
vorrei sapere come sia possibile convertire una stringa in un intero e viceversa in C#.
Grazie.

Emanuele

Risponde Alberto Falossi

La classe System.Convert espone molti metodi statici per tutte le conversioni tra tipi di dati base. Per convertire una stringa in intero devi usare:

// stringa iniziale
string theString = "123";

// intero a 16 bit
short s = System.Convert.ToInt16(theString);

// intero a 32 bit
int i = System.Convert.ToInt32(theString);

// intero a 64 bit
long l = System.Convert.ToInt64(theString);

Per l’operazione inversa puoi usare

theString = System.Convert.ToString(i);

oppure il metodo ToString presente in tutti gli oggetti .NET:

theString = i.ToString();

Saluti


Compatibilità binaria in COM

Salve,
avrei bisogno di un consiglio per realizzare un pacchetto di installazione. Si tratta di una applicazione VB6 il cui pacchetto è già in distribuzione ed è fatto in modo da installare tutto (eseguibili e librerie) in una unica directory senza registrare alcun componente. Questo ha causato problemi sulle macchine dove erano presenti nella directory di sistema le stesse DLL e OCX della mia applicazione, ma di VB5. Vorrei cambiare il pacchetto in modo che scarichi DLL ed OCX nella directory di sistema e così facendo le applicazioni installate fatte con VB6 dovrebbero continuare a funzionare. È una buona soluzione? Gli OCX e le DLL devono essere necessariamente registrati?
Ciao e grazie

Luca Dolciotti

Risponde Marco Bellinaso

Solitamente l'installazione di componenti COM (ActiveX, DLL) o di librerie condivise viene effettuata nella directory \System di Windows. In realtà per i componenti COM questo non è un obbligo, in quanto l'applicazione per caricarli non sa a priori il percorso fisico del file, ma lo estrae dal registro di Windows (questo è il motivo per cui i componenti devono necessariamente essere registrati), quindi potrebbero venire copiati in qualsiasi posto. L'installazione sotto \System è però consigliata perché evita di avere copie multiple dello stesso file sparse per il disco fisso, che è effettivamente uno dei vantaggi dei componenti COM.
A proposito della compatibilità dei nuovi file con i programmi VB5, per la libreria runtime di VB6 (MSVBVM60.DLL) il problema non si pone, in quanto il runtime di VB5 ha comunque un nome diverso. Per i controlli ActiveX o altre DLL, il programma di setup creato con il Package and Deployment Wizard controlla la versione e la data dell'eventuale file già presente su disco, e installa il file del pacchetto solo nel caso questo sia più recente. I programmi VB5 continueranno a funzionare, in quanto i nuovi componenti installati avranno compatibilità binaria o di progetto rispetto al file sovrascritto, quindi potranno essere cariati senza alcuna differenza dal programma client.
Saluti.


Richiamare una DLL da ASP

Caro Andrea,
sapendo che lavori da tempo con le DLL, ti chiedo di darmi qualche suggerimento circa lo sviluppo di una DLL che deve essere richiamata in una pagina ASP.
Quello che sto cercando di fare è l'inserimento della business logic di accesso ai dati nella DLL, in modo tale da separarla dalla pagina ASP. La cosa strana è che se provo la DLL all'interno di Visual Basic (Gruppo di progetti), essa funziona correttamente, ma se la richiamo da ASP allora ottengo un errore francamente strano.
Ti allego qui di seguito lo stralcio della chiamata da ASP

' creo il riferimento alla mia classe di oggetti
set NewObj = Server.CreateObject("BusinnesLogicLea.ClassConnection")
dim arr_par()
redim arr_par(5)

' creo la connessione al database
NewObj.AttivaConn
Set RS=server.CreateObject("ADODB.Recordset")

' l'istruzione che segue invoca una stored procedure, passando
' in un array i parametri ad essa necessari, e restituisce alla pagina
' chiamante il recordset dei risultati
set RS=NewObj.EstraiDati("qdfArticoli",1,10,arr_par())

' creo il riferimento alla mia classe di oggetti
set NewObj=server.createObject("BusinnesLogicLea.ClassConnection")
dim arr_par(3)
NewObj.AttivaConn

' inserisco i parametri della query in un array di variant (in realtà è un arraydi array, matrice di variant)
arr_par(0)= Array("pUtilizzo", adVarChar, Request.queryString("CodUtilizzo"))
arr_par(1)= Array("pCromie", adVarChar, Request.queryString("CodCromie"))
arr_par(2)= Array("pDestinazione", adVarChar, Request.queryString("CodDestinazione"))
arr_par(3)= Array("pStile", adVarChar, Request.queryString("CodStile"))

' l'istruzione che segue invoca una stored procedure, passando
' in un array i parametri ad essa necessari, e restituisce alla pagina
' chiamante il recordset dei risultati
Set session("RS")=server.CreateObject("ADODB.Recordset")
Set session("RS")=NewObj.EstraiDati("qdfMinPezSpecDecori",4,4,arr_par())

Il codice funziona correttamente se si esclude il fatto che rimane un qualche "collegamento" aperto poiché per poter aggiornare la DLL devo riavviare il Pc. Ecco l'errore che si verifica in corrispondenza dell’ultima istruzione:

Errore di run-time di Microsoft VBScript errore "800a0009' Indice non incluso nell'intervallo

Ho scorso non so quanti siti relativi ad ASP (e manuali) per cercare di capire dove potesse essere l'errore, ma senza alcun risultato. Ho cercato di aggirare i possibili conflitti tra VBScript e VB circa gli UDT, ma qualcosa deve ancora creare dei problemi.
Saluti,

Maurizio Cocchi

Risponde Andrea Chiarelli

Ciao Maurizio,
l'errore che ti viene segnalato si riferisce al passaggio dell'array arr_par come parametro del metodo EstraiDati() nell'istruzione

Session("RS") = NewObj.EstraiDati("qdfMinPezSpecDecori",4,4,arr_par())

mentre Visual Basic non ti da problemi nell'esecuzione di questa istruzione, VBScript tenta di accedere ad un elemento dell'array arr_par di cui non trova specificato l'indice. Per aggirare questo problema dovresti passare l'array senza indicare le parentesi tonde come nel seguente esempio

Session("RS") = NewObj.EstraiDati("qdfMinPezSpecDecori",4,4,arr_par)

Per quanto riguarda il problema di conflitto che ti viene segnalato all'aggiornamento della DLL, è normale in quanto la DLL rimane in memoria fino a quando non viene fermato il servizio Web. Invece di riavviare il PC basterebbe in realtà riavviare IIS o, ancora meglio, puoi abilitare dalla console di IIS l'esecuzione dell'applicazione ASP in un processo separato e, prima di aggiornare la DLL, scaricare l'applicazione dalla memoria (pulsante Unload dalle proprietà della cartella virtuale associata all'applicazione ASP).
Spero che le indicazioni che ti ho dato possano risultarti utili.