Commenti 41 27 febbraio 2011

Upload multiplo dei file con Asp.Net e JQuery

Autore: Filippo Amadori
Logo Asp.NET e JQuery

In questo post vorrei illustrarvi come creare un controllo per l’upload multiplo di immagini, documenti, pdf, file zippati... con Asp.NET.

Uplodare contemporaneamente più file, magari di estensione diversa tra loro, non è più un problema.
In rete potrete trovare diversi esempi per php ma pochissimi per Asp.NET, quindi mi sembra del tutto opportuno risolvere questa situazione di minoranza.

Fin da ora vi posso dire che Asp.NET da solo non basta (come del resto php), ma se lo relazioniamo con Adobe Flash ed un poco di JQuery, tutto diventafattibile.

Utilizzeremo un plugin per JQuery chiamato uploadify, molto performante ma a mio avviso non subito comprensibile, visto che riporta esempi esclusivi in PHP.

Per prima cosa scarichiamo il plugin gratuito dal sito ufficiale. In questo esempio utilizzeremo la versione 2.1.0 ma qualsiasi altra versione superiore può andare bene.

All’interno del pacchetto scaricato, troveremo diversi file e cartelle:

  • la versione minimized di JQuery
  • le 2 versioni full e minimized del plugin uploadify
  • Una completa documentazione in formato PDF e DOC
  • dei file .swf che ci serviranno per poter utilizzare il plugin
  • il file Adobe Flash sorgente .FLA (per chi ha voglia di implementare il progetto)
  • due cartelle con dei pacchetti per Adobe Flash e degli esempi pratici
  • due file php per capire il processo dinamico del plugin

Premetto che all’interno del file zippato e del sito ufficiale troverete un’ampia documentazione riguardante l’utilizzo del plugin in se, ma niente che spieghi come utilizzarlo con Asp.NET.

Creazione della pagina che conterrà il controllo

Tutto ciò che ci serve è dentro la cartella “example” del file zippato, esclusi il file php che nel nostro caso sono inutili.

Iniziamo con l’inserire all’interno della nostra pagina principale, tra i tag <head></head> i riferimenti ai file che dovremo utilizzare

<script type="text/javascript" src="scripts/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="scripts/swfobject.js"></script>
<script type="text/javascript" src="scripts/jquery.uploadify.v2.1.0.min.js"></script>

ora inseriamo un controllo  per l’upload dei file

<input id="uploadify1" name="uploadify1" type="file" />

a questo punto sempre all’interno dei tag <head></head>  creiamo una spazio JavaScript (<script type=”text/javascript”></script>) dentro il quale inseriremo il codice per l’implementazione del multi-upload

$(document).ready(function() {
		$('#uploadify1').uploadify({
			'uploader': 'scripts/uploadify.swf',
			'checkScript': 'scripts/Check.ashx',
			'script': 'Scripts/Upload.ashx',
			'folder': 'uploads/',
			'cancelImg': 'images/cancel.png',
			'multi': true,
			'fileDesc': 'File immagine',
			'fileExt': '*.jpg;*.gif;*.png;',
			'sizeLimit': '4194304',
			'auto': true,
			'onComplete': function (a, b, c, d, e) {
				//codice da implementare
			}
		});
	});

vi spiego velocemente le proprietà di configurazione appena impostate:

uploader = file swf che si occupa della finestra di gestione file
checkSript = file Asp.NET che si occupa di verificare se il file da caricare è già esistente nella directory di destinazione
script = file Asp.NET che si occupa di attuare l’upload per ogni file da caricare
folder = cartella di destinazione degli uploads
cancelImg = immagine del pulsante annulla
multi = indica se eseguire multi-upload o single-upload
fileDesc = descrizione dei file da caricare
fileExt = estensione del file da caricare
sizeLimit = limite di peso complessivo dei file da caricare
onComplete = funzione da eseguire al termine di ogni upload
auto = valore che indica se l’upload deve partire immediatamente dopo la selezione dei files

Tutte le proprietà (incluse quelle qui non elencate) sono ben descritte all’interno della documentazione ufficiale.

Creazione dello script Asp.NET per la verifica dei files

Ora al caricamento della pagina vedremo un pulsante per l’upload multiplo dei file, ma risulterà non funzionante se non creiamo i file Asp.NET per la gestione dei caricamenti.

Per conformità e pulizia all’interno del nostro sito, utilizzeremo dei file di gestione generici con estensione .ashx.
Questo file verificherà che i file che caricato non siano già esistenti all’interno del server:


<%@ WebHandler Language="VB" Class="Check" %>

Imports System
Imports System.Web
Imports System.IO

Public Class Check : Implements IHttpHandler
    
    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
        context.Response.ContentType = "text/plain"
        
		'recupero il percorso assoluto per la directory di uploads del server
		Dim path As String = context.Server.MapPath(context.Request.Form("folder"))
		
		Dim trovato As Boolean = False
		Dim json As String = "{"
        
		For Each s As String In context.Request.Form.AllKeys
			If Not s = "folder" Then
				'verifico se il file esiste
				If File.Exists(path & context.Request.Form(s)) Then
					'se true creo una string JSON per avvisare che il file esiste
					trovato = True
					json &= String.Format("'{0}':'{1}',", s, context.Request.Form(s))
				End If
			End If
		Next
       
		If Not trovato Then
			'se non è stata trovata nessuna corrispondenza
			json = "{}"
		Else
			'se è stata trovata nessuna corrispondenza
			json = Left(json, json.Length - 1)
			json &= "}"
		End If
        
		'rilascio la stringa JSON
		context.Response.Write(json)

	End Sub
 
    Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property

End Class

salviamo il file all’interno della cartella scripts con il nome di Check.ashx.
Questo file crea in maniera un po’ rudimentale una stringa in formato JSON che restituisce dei valori booleani per i files già esistenti all’interno del server, bloccando il medesimo upload con un messaggio di avviso.

Creazione dello script Asp.NET per il caricamento in upload dei files

questo file caricherà i file all’interno di una cartella del server:

<%@ WebHandler Language="VB" Class="Upload" %>

Imports System
Imports System.Web
Imports System.IO

Public Class Upload : Implements IHttpHandler
    
    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
		context.Response.ContentType = "text/plain"
		
		'recupero il percorso assoluto della directory di destinazione
		Dim folder As String = context.Server.MapPath(context.Request.Form("folder"))
		MsgBox(folder)
		'se la directory di destinazione non esiste la crea
		If Not Directory.Exists(folder) Then
			Directory.CreateDirectory(folder)
		End If

		'salvo su disco ogni file caricato
		If context.Request.Files.Count > 0 Then
			For n As Short = 0 To context.Request.Files.Count - 1
				Dim fileWrite As HttpPostedFile = context.Request.Files.Get(n)
				fileWrite.SaveAs(folder & System.IO.Path.GetFileName(fileWrite.FileName))
				fileWrite = Nothing
			Next
			
			'rispondo per caricamento andato a buon fine
			context.Response.Write("True")
		End If
        
	End Sub
 
    Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property

End Class

Ora tutto è completo e pronto per essere eseguito su server, visto che in locale non darebbe nessun risultato.

Un esempio completo e funzionante di upload multiplo con Asp.NET, comprensivo degli elementi appena descritti potete scaricarlo da qui.
Arrivederci al prossimo articolo



TAG:
CATEGORIE:
 

Post Correlati

Commenti

Pinux questa è cosa buona e giusta, un'ottima soluzione per caricare simultaneamente molti file sul server.
01 mar 2011
Michele non ho ben capito perchè si deve utilizzare flash
01 mar 2011
Filippo Amadori non ho ben capito perchè si deve utilizzare flash il fatto è che le finestre di dialogo "apri file" dei browser non supportano la selezione multipla dei file. la finestra di dialogo per la selezione multipla, appartiene al plugin del flash player ed è lunica in circolazione quindi è obbligatorio utilizzarlo, anche per la gestione dei file selezionati
01 mar 2011
Gianfranco percopo ho provato già questo fantasico codice m quando vado a caricare un video si blocca alla fine del caricamento. spulciando un po nelle cartelle ho visto che in realtà vengono utilizzati solo i filtri per l'immagine. forse sbaglio qualcosa io? le immagini l carica ma non file zip o video
04 mar 2011
Filippo Amadori forse sbaglio qualcosa io? le immagini l carica ma non file zip o video ho provato e non mi da problemi, in quanto il controllo passa alla pagina asp.net, un serie di dati in formato byte. hai provato ad umentare le capacità di upload del server. di default i server accettano solo 4mbyte in upload, tramite il web.config puoi aumentare la capacità di upload. fammi sapere se continui ad avere problemi.
06 mar 2011
Gianfranco grande filippo, non sapevo dei 4 mega. cavolo, grazie. comunque posto i parametri che ho settato magari può aiutare qualcuno:

ho cambiato sia il valore in fileext espresso in byte portatndolo ad un 1gb;

'sizelimit': '1073741824',

e poi il file web.config nel seguente modo. in questo caso il valore è espresso in kb

<httpruntime
executiontimeout="110"
maxrequestlength="1048576"
requestlengthdiskthreshold="80"
usefullyqualifiedredirecturl="false"
minfreethreads="8"
minlocalrequestfreethreads="4"
apprequestqueuelimit="5000"
enablekerneloutputcache="true"
enableversionheader="true"
requirerootedsaveaspath="true"
enable="true"
shutdowntimeout="90"
delaynotificationtimeout="5"
waitchangenotification="0"
maxwaitchangenotification="0"
enableheaderchecking="true"
sendcachecontrolheader="true"
apartmentthreading="false" />

grazie ancora e forza .net

06 mar 2011
Filippo Amadori posto i parametri che ho settato magari può aiutare qualcuno grande gianfranco, questi sono commenti utili per tutti che il .net sia con te. :-)
07 mar 2011
Lorenzo grande filippo, proprio quello che cercavo! e complimenti per il bel tutorial ;) vorrei però chiederti una cosa: io avrei bisogno, dal mio sito che sarà prossimamente online, di effettuare l'upload di file verso uno spazio web a cui bisogna accedere utlizzando username e password. con l'oggetto fileupload di asp mi è permesso trasferire i file via ftp, specificando le credenziali qualora ce ne fosse bisogno, ma con uploadify non so assolutamente come fare. ti chiedo scusa, sono agli inizi sia con js che col .net, forse ho capito male, ma sembra che i file possano essere uppati solo in una cartella del dominio sul quale è presente il sito. avresti qualche consiglio da darmi? grazie tante.
12 apr 2011
Raffaele ciao, ottimo tutorial, un problema: perchè mi restituisce un errore (http error) se cerco di caricare un qualunque file? grazie
25 mag 2011
Filippo Amadori hai verificato, il discorso dei 4megabyte (vedi sopra) e soprattutto i permessi delle cartelle
25 mag 2011
Raffaele il file pesa solo 55 kb... quindi lo escluderei. i permessi li ho settati su 777, è corretto??? continua a farmi tutto l'upload ma alla fine mi da l'error e...
25 mag 2011
Filippo Amadori ho verificato il tool ed il codice è corretto, l'unica cosa che mi viene in mente è qualche errore nei permessi del server, ma senza verificare come stai utilizzando il tool non saprei cos'altro dire
25 mag 2011
Raffaele penso sia colpa dei permessi di aruba..... che palle...:) garzie per i consigli!!! se trovo la soluzione la posto!
25 mag 2011
Alex ciao complimenti per il tutorial. ho un problema, non riesco a salvare sul db il nome del file caricato. puoi farmi un esempio per favore ? grazie ciao
31 mag 2011
Filippo Amadori ciao alex, all'interno del file upload.ashx, trovi un ciclo commentato come: "salvo su disco ogni file caricato". questo ciclo salva sul server ogni file caricato col proprio nome di origine. prima dell'ordine di chiusura ciclo "next" inserisci il codice ado.net per registrare i dati nel database. es. for n as short = 0 to context.request.files.count - 1 dim filewrite as httppostedfile = context.request.files.get(n) filewrite.saveas(folder & system.io.path.getfilename(filewrite.filename)) dim con as new sqlconnection("stringa di connessione") dim com as new sqlcommand("insert into tabella (nomefile) values( @nomefile)", con) com.parameters.clear() com.parameters.addwithvalue("nomefile",filewrite.filename) con.open com.executenonquery() con.close com.dispose con.dispose filewrite = nothing next
31 mag 2011
Alex ciao grazie per la velocità con la quale mi hai risposto. ok sono riuscito a inserire il nome ma se dovessi avere anche un paio di textbox? devo sempre lavorare dentro lo user control? grazie ciao
31 mag 2011
Filippo Amadori ciao grazie per la velocità con la quale mi hai risposto. de nada! puoi passare altri valori al file upload.ashx tramite: 1. la proprietà data della funzione uploadify() incorporata tra i tag <script> (sulla guida ufficiale trovi tutti i dettagli) es. $('#uploadify1').uploadify({ 'uploader': 'scripts/uploadify.swf', 'checkscript': 'scripts/check.ashx', 'script': 'scripts/upload.ashx', 'folder': 'uploads/', 'cancelimg': 'images/cancel.png', 'multi': true, 'filedesc': 'file immagine', 'fileext': '*.jpg;*.gif;*.png;', 'sizelimit': '4194304', 'auto': true, 'data': 'var1=miavar&var2=miavar', 'oncomplete': function (a, b, c, d, e) { //codice da implementare } 2. puoi passare valori tramite query string al file upload.ashx sempre tramite la funzione uploadify() incorporata tra i tag <script> es. $('#uploadify1').uploadify({ 'uploader': 'scripts/uploadify.swf', 'checkscript': 'scripts/check.ashx', 'script': 'scripts/upload.ashx?var1=miavar&var2=miavar', 'folder': 'uploads/', 'cancelimg': 'images/cancel.png', 'multi': true, 'filedesc': 'file immagine', 'fileext': '*.jpg;*.gif;*.png;', 'sizelimit': '4194304', 'auto': true, 'oncomplete': function (a, b, c, d, e) { //codice da implementare } });
31 mag 2011
Alex grazie ma ho dei problemi con i valori sto cercando anche sulla guida ma niente. supponiamo di passare una textbox di una pagina .net ho provato cosi ma non funziona --------------------- 'scriptdata': 'var cognomevalue=$(#<%=cognome.clientid %>)'.val(), --------------- per recuperarla prima di fare una insert nel db? ------------------- cognomevalue = context.request["cognome"]; ---------------------- ovviamente non funziona.. se vuoi ti scrivo in privato per non trasformare questo bel tutorial in una lezione sul mio problema grazie
01 giu 2011
Filippo Amadori 'scriptdata': 'var cognomevalue=$(#<%=cognome.clientid %>)'.val(), così non va bene, prova così: 'scriptdata': $('#<%=cognome.clientid %>').val(), cognomevalue = context.request["cognome"]; anche così non va bene, prova così: // c# cognomevalue = context.request.form["cognome"];
01 giu 2011
Filippo Amadori scusa ho sbagliato a scrivere: 'scriptdata': 'cognomevalue=' + $('#<%=cognome.clientid %>').val(),
01 giu 2011
Alex ciao ti ringrazio molto per la tua disponibilità purtroppo ho un problema. credo che la variabile "cognome" sia valorizzata in js ma non quando vado per scriverla nel db che di fatto non inserisce nulla. e' corretto recuperarla cosi nell'hander? (vb.net) dim miavariabile as string = context.request.form("cognomevalue") grazie mille ciao
03 giu 2011
Filippo Amadori e' corretto recuperarla cosi nell'hander? (vb.net) dim miavariabile as string = context.request.form("cognomevalue") è corretto
03 giu 2011
casino online mi piace il tuo sito. e'una informazione molto utile.
08 giu 2011
Alex ciao grazie dei tuoi consigli ci sono quasi riesco a passare il nome del file nel db ma non il valore di una textbox premesso che sono in ambiente vb.net -------------------- ho questa text <asp:textbox id="cognome" runat="server"></asp:textbox> nello script js ho provato ad inserire questo valore 'scriptdata': 'cognomevalue=' + $('#<%=cognome.clientid %>').val(), e a richimarlo nell'handler prima di inviarlo al db dim miocognome as string = context.request.form("cognomevalue") ma mi da errore 500 se elimino questo pezzo lo script funziona qualche suggerimento? grazie ciao
09 giu 2011
Filippo Amadori ti chiedo scusa, non utilizzando spesso la prorpietà scriptdata ho forse dimenticato il suo funzionamento. prova così: 'scriptdata':{'cognomevalue' : $('#<%=cognome.clientid %>').val()},
09 giu 2011
Massimiliano ciao filippo

quando provo a caricare ho lo stesso problema di raffaele, mi dice http error.

ho anche io il sito sul server aruba, ho provato a mettere anche tutto il codice in /public/ (cartella con tutti i permessi) ma non ho risolto. :(

09 giu 2011
Filippo Amadori io utilizzo spesso aruba e non mi da problemi quindi dovrei vedere il tuo codice. dentro la cartella public, ci devono andare solo i file caricati e non tutto il codice, o per lo meno non è necessario
09 giu 2011
Massimiliano ehm perdonami la figuraccia ma mi sa che il mio dominio hosting aruba non supporta il .net

io programmo ancora in asp ma mi sembra strano che aruba non supporti il .net dato che è compreso nell'acquisto del dominio hosting windows.

nel pannello di controllo del mio sito mi dice:

.net framework version: errore
sistema operativo: microsoft windows 2003
iis: microsoft-iis/6.0
mdac: 2.82.3959.0

per cui credo che possa essere questo il problema, che dici?
09 giu 2011
Gianfranco hai provato a compilare con il 3.5 anzicche con il 4.0. aruba regge solo il 3.5. anch'io ebbi lo stesso problema.
09 giu 2011
Massimiliano grazie gianfranco della dritta,

scusami ma... come si fa? :(
10 giu 2011
Filippo Amadori da visual studio o visual web developer clicca col destro sul nome dell'applicazione, poi scegli pagine delle proprieta. dalla scheda compilazione scegli il tipo di framework
10 giu 2011
Massimiliano ehm... ok ok abbandonerò il mio vecchio notepad++.
grazie a tutti, vi faccio sapere se ho novità.
10 giu 2011
casino online mi piace il tuo sito. e 'una cosa molto utile. grazie
10 giu 2011
Alex ciao filippo ti ringrazio moltissimo per l'aiuto che mi stai dando putroppo niente non ce verso di passare una textbox..in vb.bet <asp:textbox id="cognome" runat="server"></asp:textbox> nel js di jquery 'scriptdata': { 'cognomevalue': $('#<%=cognome.clientid %>').val() }, nell'handler prima di caricare nel db dim miocognome as string = context.request.form("cognomevalue") ---------------- ho provato a creare una nuova funzione all'onclick di un button function upload() { $('#custom_file_upload').uploadifysettings('postdata', { cognomevalue: $('#cognome.clientid').val() }); $('#custom_file_upload').uploadifyupload(); } ma niente....... riesco a passare il nome del db ma non altri parametri.. hai provato a simulare anche tu il fatto di inviare contestualmente dei parametri? grazie mille ciao
10 giu 2011
Filippo Amadori nel mio cms puoi generare un numero infinito di gallerie e con l'upload multiplo carichi più immagini contemporaneamente all'interno della galleria, della quale passo l'id al database tramite un hiddenfield e lo script di uploadfy. questa funzione è presente nella maggior parte dei siti che ho fatto i quali risiedono nell'host aruba. lo script è quello che ti ho passato, purtroppo non so cos'altro dirti se non di ricontrollare i parametri dello script e verificare che jquey passi veramente il valore della textbox
10 giu 2011
casino online wow! che l'articolo di fresco! grazie per la condivisione =)
22 giu 2011
Filippo Amadori spero di essere utile a tutti rispondendo con questo articolo: http://goo.gl/kag97
23 giu 2011
the specialist salve e complimenti per il tutorial. è possibile scaricare il file dell'esempio dato che il link non è funzionante? graziiee
05 set 2011
Filippo Amadori Effettivamente nel trasferimento dal vecchio blog devo essermi perso qualcosa in giro ora è tutto ok
05 set 2011
Giacomo Il file check non funziona, dà errore in caso venga effettuato l'upload di un file già esistente sul server.... Credo che non sia corretta la stringa json che viene restituita..
Qualche soluzione?
29 set 2011
Angelo ciao, Selezionando il file da uploadare ottengo solo la visualizzazione della grafica di invio del file con il peso dello stesso, ma nessun azione di invio; ho caricato sul server (non Aruba)i files e le cartelle del file zip nella root del sito, ho creato una cartella 'Servizi' per cui ho richiesto ed ottenuto i permessi di letura e scrittura. Ho modificato il nome cartella in folder in 'servizi' e ho provato anche a inserire il percorso fisico, ma niente... il sito originale è in asp classico.
11 apr 2012
Lascia un commento