Durante lo sviluppo di applicazioni web può capitare di dover effettuare l'upload di file, ma si è spesso costretti a limitarne le dimensioni. Magari può essere dovuto a questioni di sicurezza o per evitare di "appesantire" troppo il file system del server. Alcune volte però per requisiti applicativi è necessario l'invio di files di grosse dimensioni (anche più di 100 MB). Immaginiamo ad esempio il caso di un repository online (magari condiviso fra le diverse sedi di un'azienda).
L'approccio presentato in questo articolo si basa su un servizio WCF per la ricezione lato server dei dati: l'idea di base è di dividere il file in pacchetti ed inviarli in maniera sequenziale invocando uno o due metodi esposti dal servizio remoto (in base alla dimensione totale del file).
Prima di tutto abbiamo bisogno di una classe lato web service che gestisca i pacchetti in entrata:
public class UploadModel
{
public Guid ID { get; private set; }
public string Filename { get; private set; }
public int PartsLeft { get; set; }
}Come si può notare, la classe espone una property ID di tipo Guid per poterne garantire l'univocità. All'interno del servizio remoto creeremo infatti uno static Dictionary
Il primo metodo da invocare ci consente di far iniziare la procedura e restituisce l'ID dell'UploadModel appena creato:
public string BeginUpload(string filename, byte[] buffer, int numParts)
{
try
{
if (null != buffer && 0 != buffer.Length)
{
var model = new UploadModel(filename, numParts - 1);
AppendDataToFile(model, buffer);
if (0 == model.PartsLeft)
return EndUpload(model);
_uploadsDict.Add(model.ID , model);
// facciamo restituire l'ID per poterlo usare successivamente
return model.ID.ToString();
}
return "FAIL";
}
catch (Exception ex)
{
throw ex;
}
}Questo metodo non fa altro che creare una nuova istanza di UploadModel e accodare il primo pacchetto di dati. Per l'implementazione del metodo AppendDataToFile possiamo vedere il progetto di esempio allegato.
Nella firma abbiamo incluso anche il numero di pacchetti rimasti: se è 0 procediamo con il metodo EndUpload:
private string EndUpload(UploadModel model)
{
try
{
if (null != model)
{
// l'upload è terminato, non abbiamo più bisogno di mantenere
// l'oggetto nel dizionario
if (_uploadsDict.ContainsKey(model.ID))
_uploadsDict.Remove(model.ID);
/*********/
// Qui va inserita la logica di gestione del file appena ricevuto
/*********/
return "OK";
}
return "FAIL";
}
catch (Exception ex)
{
throw ex;
}
}Il metodo è marcato come private perché non c'è necessità che venga invocato dai client. Se infatti il numero di pacchetti è maggiore di 1, useremo quest'altra funzione:
public string UploadBytes(string key, byte[] buffer)
{
try
{
if (null != buffer && 0 != buffer.Length)
{
var guid = new Guid(key);
// Controlliamo che la chiave corrisponda ad un upload valido,
// accodiamo il pacchetto e riduciamo il numero dei pacchetti rimasti
UploadModel model = null;
if(_uploadsDict.TryGetValue(guid, out model))
{
AppendDataToFile(model, buffer);
model.PartsLeft--;
}
// Anche qui se abbiamo terminato i pacchetti procediamo con EndUpload
if (0 == model.PartsLeft)
return EndUpload(model);
return model.ID.ToString();
}
return "FAIL";
}
catch (Exception ex)
{
throw ex;
}
}In allegato troviamo una soluzione con il progetto web contenente il servizio ed un piccolo progetto di test in Silverlight.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Creare una libreria CSS universale: Nav menu
Controllare la telemetria con .NET Aspire
Ridurre il reflow ottimizzando il CSS
Creare un agente A2Acon Azure Logic Apps
Path addizionali per gli asset in ASP.NET Core MVC
Gestione file Javascript in Blazor con .NET 9
Utilizzare il metodo IntersectBy per eseguire l'intersection di due liste
Generare una User Delegation SAS in .NET per Azure Blob Storage
Eseguire script pre e post esecuzione di un workflow di GitHub
Usare i settings di serializzazione/deserializzazione di System.Text.Json di ASP.NET all'interno di un'applicazione non web
Autenticazione di git tramite Microsoft Entra ID in Azure DevOps
Disabilitare le run concorrenti di una pipeline di Azure DevOps
I più letti di oggi
- Usare Bootstrap con ASP.NET MVC 4
- Rimuovere dalla cache una pagina in OutputCache
- Il SP2 di Windows Vista e Windows Server 2008 arriva alla RC
- Rilasciata patch di sicurezza per la vulnerabilità sulla crittografia di ASP.NET
- jQuery raggiunge la versione 1.7
- Real World ASP.NET Best Practices
- Transact-SQL Programmazione avanzata
- Tra i 1000 siti più visitati è IIS il più usato
- Le differenze di VS 2005 Express, Professional e Team System
- .NET Framework 2.0 Code Coverage Edition per la compatibilità con la 1.x


