Upload file in Asp.Net

Classe per gestire l'upload di file in Asp.Net basandosi su un controllo FileUpload.

Una funzionalità comune nelle applicazioni web è l'upload di file, ovvero il trasferimento di file da un client a un server tramite browser.
E' bene assicurarsi che vengano caricati solo file idonei, imponendo limiti sui tipi di file e sul peso in Kilobyte; nel caso di immagini si controllano anche le dimensioni in pixel.

Per evitare di riscrivere spesso il codice ho creato una classe che include già tutte queste funzionalità, appoggiandosi al controllo FileUpload di Asp.Net il quale prevede un'interfaccia grafica con la quale l'utente può selezionare un file, ed effettua l'upload vero e proprio.

Defizione della classe

Solo per progetti di tipo Web Site:

creare la cartella speciale App_Code se non è già presente:

Tasto destro sul progetto >> Add Asp.Net Folder >> App_Code

Aggiungere un file di tipo classe (.vb):

Tasto destro su App_Code >> Add New Item >> Class

Cancellare tutto il contenuto e copiare la definizione della classe sottostante.
Modificare il nome del namespace, che in questo esempio ho chiamato DevOClock_SRB.

Imports Microsoft.VisualBasic
Imports System.Drawing

Namespace DevOClock_SRB

    ''' <summary>
    ''' Classe per la gestione degli upload usando un controllo FileUpload
    ''' </summary>
    ''' <remarks></remarks>
    Public Class UploadManager

        Private Property _FileUploadObject As FileUpload
        Public Property FileUploadObject() As FileUpload
            Get
                Return _FileUploadObject
            End Get
            Set(value As FileUpload)
                If value.FileName.Length > 0 Then
                    _FileUploadObject = value
                    _FileToUpload = value.FileName.ToLower
                Else
                    Throw New Exception("Il nome del file non può essere vuoto<br />")
                End If
            End Set
        End Property

        Private Property _FileToUpload As String                'Nome del file da caricare
        Public Property CheckExtension As Boolean                'Se controllare o no l'estesione del file
        Public Property AcceptedExtensions As New List(Of String)    'Lista delle estensioni accettabili
        Public Property CheckHeight As UploadManager_ImageCheck    'Solo per le immagini: se e come controllare l'altezza
        Public Property CheckWidth As UploadManager_ImageCheck    'Solo per le immagini: se e come controllare la larghezza
        Public Property RequiredHeight As UShort                'Altezza richiesta per l'immagine
        Public Property RequiredWidth As UShort                    'Larghezza richiesta per l'immagine
        Private Property _PhysicalPath As String                'Cartella del server in cui salvare il file (percorso fisico)

        Public Property Path As String
            Get
                Return _PhysicalPath
            End Get
            Set(value As String)
                If Not System.IO.Directory.Exists(value) Then
                    Throw New Exception("La cartella specificata non è esistente<br />")
                Else
                    _PhysicalPath = value
                End If
            End Set
        End Property

        ''' <summary>
        ''' Crea un nuovo UploadManager
        ''' </summary>
        ''' <param name="fileUploadControl">Controllo FileUpload</param>
        ''' <param name="PathToSave">Percorso fisico in cui salvare il file</param>
        ''' <remarks></remarks>
        Public Sub New(ByRef fileUploadControl As FileUpload, ByVal PathToSave As String)
            CheckExtension = False
            CheckHeight = UploadManager_ImageCheck.NoCheck
            CheckWidth = UploadManager_ImageCheck.NoCheck
            FileUploadObject = fileUploadControl
            Path = PathToSave
        End Sub

        ''' <summary>
        ''' Effetua l'upload del file
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function UploadFile() As Boolean

            Dim errMessage As String = String.Empty

            'Controllo se esiste già un file con lo stesso nome
            If System.IO.File.Exists(Path & "\" & _FileToUpload) Then
                Throw New Exception("Esiste già un file chiamato " & _FileToUpload & "<br />")
                Return False
            End If

            'Controllo che l'estensione del file sia valida
            If CheckExtension Then
                UploadFile = False
                For Each ext As String In AcceptedExtensions
                    If _FileToUpload.ToLower.EndsWith(ext) Then
                        UploadFile = True
                        Exit For
                    End If
                Next
                If Not UploadFile Then
                    Throw New Exception(String.Format("L'estensione {0} non è valida.<br />", _FileToUpload.Substring(_FileToUpload.Length - 4)))
                    Return False
                End If
            End If

            'Carico il file
            Try
                _FileUploadObject.SaveAs(Path & "\" & _FileToUpload)
            Catch ex As Exception
                Throw New Exception(ex.Message)
            End Try

            'Controllo che la larghezza dell'immagine sia valida
            If CheckWidth <> UploadManager_ImageCheck.NoCheck Then
                Dim myImage As Image
                myImage = Image.FromFile(Path & "\" & _FileToUpload)

                Select Case CheckWidth
                    Case UploadManager_ImageCheck.Exact
                        If myImage.Width <> RequiredWidth Then
                            UploadFile = False
                            errMessage = String.Format("La larghezza dell'immagine deve essere di {0} px<br />", RequiredWidth.ToString)
                        End If
                    Case UploadManager_ImageCheck.Maximum
                        If myImage.Width > RequiredWidth Then
                            UploadFile = False
                            errMessage = String.Format("La larghezza dell'immagine non può superare i {0} px<br />", RequiredWidth.ToString)
                        End If
                    Case UploadManager_ImageCheck.Minimum
                        If myImage.Width < RequiredWidth Then
                            UploadFile = False
                            errMessage = String.Format("La larghezza dell'immagine deve essere almeno di {0} px<br />", RequiredWidth.ToString)
                        End If
                End Select

                myImage.Dispose()
                myImage = Nothing
            End If

            'Controllo che l'altezza dell'immagine sia valida
            If CheckHeight <> UploadManager_ImageCheck.NoCheck Then

                Dim myImage As Image
                myImage = Image.FromFile(Path & "\" & _FileToUpload)

                Select Case CheckHeight
                    Case UploadManager_ImageCheck.Exact
                        If myImage.Height <> RequiredHeight Then
                            UploadFile = False
                            errMessage &= String.Format("L'altezza dell'immagine deve essere di {0} px<br />", RequiredHeight.ToString)
                        End If
                    Case UploadManager_ImageCheck.Maximum
                        If myImage.Height > RequiredHeight Then
                            UploadFile = False
                            errMessage &= String.Format("L'immagine supera l'altezza di {0} px<br />", RequiredHeight)
                        End If
                    Case UploadManager_ImageCheck.Minimum
                        If myImage.Height < RequiredHeight Then
                            UploadFile = False
                            errMessage &= String.Format("L'altezza dell'immagine deve essere almeno di {0} px<br />", RequiredHeight)
                        End If
                End Select

                myImage.Dispose()
                myImage = Nothing
            End If

            'Se le dimensioni dell'immagine non sono idonee, cancello il file
            If errMessage.Length > 0 Then
                Try
                    System.IO.File.Delete(Path & "\" & _FileToUpload)
                Catch ex As Exception
                    Throw New Exception("Non è stato possibile eliminare il file. " & ex.Message)
                End Try

                Throw New Exception(errMessage)
                Return False
            End If

            Return True
        End Function

    End Class

    Public Enum UploadManager_ImageCheck
        NoCheck = 0
        Minimum = 1
        Exact = 2
        Maximum = 3
    End Enum

End Namespace

Utilizzo della classe

La pagina .aspx deve contenere un controllo FileUpload e un pulsante per effettuare il PostBack.
Nella pagina di code behind bisogna gestire l'evento click del pulsante.

Per poter usare la classe è necessario importare il namespace:

Imports DevOClock_SRB

Nel seguente esempio si vuole caricare un'immagine con larghezza massima 350 pixel.
Si crea un'istanza della classe, si impostano le proprietà e infine si richiama il metodo UploadFile.

uplManagerTn = New UploadManager(uplTn, Server.MapPath(imgPathTn))
With uplManagerTn
	.CheckHeight = UploadManager_ImageCheck.NoCheck
	.CheckWidth = UploadManager_ImageCheck.Maximum
	.RequiredWidth = 350
	.CheckExtension = True
	.AcceptedExtensions.Add(".gif")
	.AcceptedExtensions.Add(".jpg")
	.AcceptedExtensions.Add(".jpeg")
	.AcceptedExtensions.Add(".png")
End With

uplManagerTn.UploadFile()

Qui invece si carica un'immagine di dimensione esattamente 150x150 pixel:

If uplImmagine.FileName.Length > 0 Then
    Dim uplManager As UploadManager
    uplManager = New UploadManager(uplImmagine, Server.MapPath(serverFolder))
    With uplManager
        .CheckExtension = True
        .AcceptedExtensions.Add(".gif")
        .AcceptedExtensions.Add(".png")
        .AcceptedExtensions.Add(".jpg")
        .AcceptedExtensions.Add(".jpeg")
        .CheckHeight = UploadManager_ImageCheck.Exact
        .RequiredHeight = 150
        .CheckWidth = UploadManager_ImageCheck.Exact
        .RequiredWidth = 150
    End With

    Try
        If uplManager.UploadFile() Then
            lblOutput.Text &= "Immagine caricata con successo sul server."
        Else
            'lblOutput.Text &= "L'immagine non è stata caricata. Sarà usata un'immagine di default."
        End If
    Catch ex As Exception
        lblOutput.Text &= ex.Message
    End Try
    uplManager = Nothing
End If

Notare che Intellisense fornisce un grande aiuto nell'impostazione delle proprietà proponendo i valori che sono stati definiti nell'Enum.

Implementazioni future

Aggiungere il controllo sul peso in kilobyte del file.

Autore: Sergio Roberto Boarina