In questo articolo vedremo alcune operazioni che si possono fare con il database NoSQL più conosciuto al mondo, MongoDB, ed il linguaggio di programmazione C#, con la versione 9 del Framework .Net
In particolare, l’inserimento, modifica, cancellazione e visualizzazione dei file da gestire tramite database.
Utilizzeremo la versione MongoDB Community, che è la versione gratuita da installare sul pc, e l’ambiente di sviluppo Visual Studio 2022 Community, anch’essa gratuita.
Creazione del progetto
Utilizzando un progetto precedente per la gestione del database MongoDB, come visto negli articoli precedenti (qui https://www.iprogrammatori.it/articoli/microsoft-net-framework/csharp-operazioni-crud-sul-database-mongodb-prima-parte la prima parte delle operazioni CRUD) in caso di non disponibilità, creare un nuovo progetto di tipo Windows Application, seguendo le prime operazioni descritte nell’articolo indicato.
Una volta creato il progetto, o aperto uno esistente sempre in ambito di gestione dati di MongoDB, aggiungiamo un nuovo pulsante, nel quale faremo le varie operazioni di gestione.
Aggiungiamo al progetto 4 pulsante, uno avrà il nome di tipo “BtnInserisci”, un altro pulsante con il nome del controllo impostato su “BtnModifica”, un altro con il nome “BtnElimina” ed infine l’ultimo, con il valore “BtnVisualizza”. Le proprietà “Text” possiamo impostarle a piacimento, oppure rispettivamente “Inserisci”, “Modifica”, “Elimina”, e “Visualizza”.
Nel progetto dobbiamo aggiungere tramite Nuget, se non è presente, il pacchetto “MongoDB.Driver”.
Stesura del codice
Passiamo in visualizzazione codice della form, ed in alto sopra ad ogni dichiarazione, inseriamo lo spazio dei nomi per la gestione delle classi per il database MongoDB.
Nella parte in alto, sopra ad ogni dichiarazione, aggiungiamo lo spazio dei nomi, di seguito il frammento delle suddette dichiarazioni.
C#
using MongoDB.Bson;
using MongoDB.Driver;
Facciamo doppio click sul pulsante con il nome “BtnInserisci”, in modo da passare in visualizzazione codice nell’evento click del pulsante stesso.
Dopo aver creato un oggetto di tipo “MongoClient” per collegarsi al server database, tramite il metodo “GetDatabase”, otteniamo il database di nostro interesse, mentre il metodo “GetCollection”, otteniamo un oggetto di tipo “IMongoCollection” della collection dove vorremmo inserire il file. L’aggiunta del file avviene tramite un oggetto di tipo “BsonDocument”, impostando una proprietà di tipo array dello stream dati del file.
Il metodo “InsertOne” permette di inserire il dato nella collection.
Di seguito si riporta il frammento di codice delle suddette operazioni.
C#
private void BtnInserisciFile_Click(object sender, EventArgs e)
{
try
{
string percorsoNomeFile = "C:\\Varie\\faro.bmp";
//Rilevo Array byte del file
byte[] fileArrayBytes = File.ReadAllBytes(percorsoNomeFile);
//creo un documento BsonDocument con l'array byte del file e altre informazioni
var nuovoFile = new BsonDocument
{
{ "NomeFile", Path.GetFileName(percorsoNomeFile) }, // Nome del file
{ "Contenuto", fileArrayBytes }, // Contenuto del file come array di byte
{ "tipoFile", Path.GetExtension(percorsoNomeFile) } // tipo file
};
//Ottengo la collection dati
var clientMongoDB = new MongoClient("mongodb://localhost:27017");
var database = clientMongoDB.GetDatabase("Amministrazione");
var collection = database.GetCollection<BsonDocument>("Dati");
//Inserisco il nuovo documento nella collection
collection.InsertOne(nuovoFile);
MessageBox.Show("File inserito con successo nella collection 'Dati'.");
}
catch (MongoCommandException ex)
{
MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
All’oggetto BsonDocument, possiamo passare una proprietà di tipo “BsonBinaryData”, per dare una migliore definizione al campo del dato .
Di seguito si riporta il frammento di codice di tale utilizzo.
C#
private void BtnInserisciFile_Click(object sender, EventArgs e)
{
try
{
//Oggetto del client MongoDB
var clientMongoDB = new MongoClient("mongodb://localhost:27017");
//Seleziono il database dal quale rilevare le collection
var database = clientMongoDB.GetDatabase("Amministrazione");
//Creo una collection per i file nel caso che non esiste
if (!database.ListCollectionNames().ToList().Contains("Dati"))
{
database.CreateCollection("Dati");
}
//Seleziono la collection per inserire il file
var collection = database.GetCollection<BsonDocument>("Dati");
//Crea un nuovo documento BsonDocument con l'array byte del file e altre informazioni
var filePath = "C:\\Varie\\faro.jpg";
if (!File.Exists(filePath))
{
MessageBox.Show("Il file specificato non esiste.");
return;
}
var fileBytes = File.ReadAllBytes(filePath);
//Creo un nuovo documento BsonDocument con il file e altre informazioni
var nuovoFile = new BsonDocument
{
{ "NomeFile", Path.GetFileName(filePath) }, // Nome del file
{ "Contenuto", new BsonBinaryData(fileBytes, BsonBinarySubType.Binary) }, // Contenuto del file come array di byte
{ "DataCreazione", DateTime.Now } // Data di creazione del file
};
collection.InsertOne(nuovoFile);
MessageBox.Show("File inserito con successo.");
}
catch (MongoCommandException ex)
{
MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Una precisazione sull’inserimento dei file, nel caso che il file supera i 16 MB, verrà generato un errore, come mostrato in figura 1.

Figura 1 – L’errore per un file che supera i 16 MB
In questi casi, occorre usare la classe “GridFSBucket” , che permette di gestire i file di grandi dimensioni.
Per utilizzare questa classe, occorre aggiungere lo spazio dei nomi “GridFS”, come riportato nel frammento di codice qui di seguito.
C#
using MongoDB.Driver.GridFS;
Per inserire il file di grandi dimensioni, occorre utilizzare il metodo “UploadFromStream”, passando come parametri nome file e lo strem dati del file.
Di seguito il frammento di codice per inserire un file superiore ai 16 MB.
C#
//Oggetto del client MongoDB
var clientMongoDB = new MongoClient("mongodb://localhost:27017");
//Seleziono il database dal quale rilevare le collection
var database = clientMongoDB.GetDatabase("Amministrazione");
var filePath = "C:\\Varie\\file20Mb.dll";
if (!File.Exists(filePath))
{
MessageBox.Show("Il file specificato non esiste.");
return;
}
var gridFSbucket = new GridFSBucket(database);
//Leggo il file e lo converto in array di byte
using (var fileStream = new FileStream(filePath, FileMode.Open))
{
var fileId = gridFSbucket.UploadFromStream(Path.GetFileName(filePath), fileStream);
}
Il file sarà presente in una “collection” denominata “fs.files”, il tutto come mostrato in figura 2.

Figura 2 – Il fine da 20 mb nella collection per i grandi file
Passiamo in visualizzazione grafica della form e facciamo doppio click sul pulsante “Visualizza”, in modo da passare in visualizzazione codice nell’evento clic del pulsante.
In questo evento, rileviamo il file di nostro interesse, in particolare applicheremo un filtro per il nome del file, ed una volta ottenuto il documento, tramite la proprietà “AsByteArray” di un documento, rileviamo l’array del file.
Di seguito si riporta il frammento di codice delle suddette operazioni.
C#
private void BtnDownloadFile_Click(object sender, EventArgs e)
{
try
{
//Oggetto del client MongoDB
var clientMongoDB = new MongoClient("mongodb://localhost:27017");
//Seleziono il database dal quale rilevare le collection
var database = clientMongoDB.GetDatabase("Amministrazione");
//Selezioniono la collection
var collection = database.GetCollection<BsonDocument>("Dati");
//Recupero il documento che contiene il file
var filtro = Builders<BsonDocument>.Filter.Eq("NomeFile", "faro.bmp");
//rilevo il file
var documentoFile = collection.Find(filtro).FirstOrDefault();
if (documentoFile == null)
{
MessageBox.Show("Documento non trovato.");
return;
}
//Rilevo l'array di byte del file dal documento
var fileBytes = documentoFile["Contenuto"].AsByteArray;
//Variabile per il salvataggio del file
var percorsoSalvataggio = "C:\\Varie\\faro_scaricato.bmp";
File.WriteAllBytes(percorsoSalvataggio, fileBytes);
MessageBox.Show("File scaricato con successo in: " + percorsoSalvataggio);
}
catch (MongoCommandException ex)
{
MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Nel caso che invece si vuole scaricare un file di grandi dimensioni, dobbiamo utilizzare il metodo “DownloadToStream” della classe “GridFsBucket”, che permette di gestire file di grandi dimensioni.
Di seguito si riporta il frammento di codice, che rilevo il documento nella collection “fs.files” dove sono presenti file di grandi dimensioni, ed ottenuto il documento lo scarica.
C#
private void BtnDownloadFile_Click(object sender, EventArgs e)
{
try
{
//Oggetto del client MongoDB
var clientMongoDB = new MongoClient("mongodb://localhost:27017");
//Seleziono il database dal quale rilevare le collection
var database = clientMongoDB.GetDatabase("Amministrazione");
//Recupero il documento che contiene il file
var filtro = Builders<BsonDocument>.Filter.Eq("filename", "file20Mb.dll");
//rilevo il file di grandi dimensioni
var documentoFile = database.GetCollection<BsonDocument>("fs.files").Find(filtro).FirstOrDefault();
//Verifico se il documento esiste
if (documentoFile == null)
{
MessageBox.Show("Documento non trovato.");
return;
}
//Rilevo l'id del file
var fileId = documentoFile["_id"].AsObjectId;
//Creo un oggetto GridFSBucket per gestire i file di grandi dimensioni
var gridFSbucket = new GridFSBucket(database);
//Variabile per il salvataggio del file
var percorsoSalvataggio = "C:\\Varie\\file20Mb_scaricato.dll";
//Scarico il file dal database e lo salvo nel percorso specificato
using (var fileStream = new FileStream(percorsoSalvataggio, FileMode.Create))
{
gridFSbucket.DownloadToStream(fileId, fileStream);
}
MessageBox.Show("File scaricato con successo in: " + percorsoSalvataggio);
}
catch (MongoCommandException ex)
{
MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Aggiornamento
Può capitare che in un determinato documento, dovremmo aggiornare il file stesso.
La modifica del campo file, è la stessa tecnica che avviene per modificare i vari campi di un documento, utilizzando il metodo “Set” della classe “Builders”. Tramite il metodo “updateOne” della classe “IMongoCollection”, effettuo le modifiche del documento nella collection.
Tramite la proprietà “ModifiedCount” dell’oggetto “UpdateResult”.
Di seguito si riporta il codice, delle suddette operazioni.
C#
private void BtnAggiornaFile_Click(object sender, EventArgs e)
{
try
{
//Oggetto del client MongoDB
var clientMongoDB = new MongoClient("mongodb://localhost:27017");
//Oggetto per la gestione del database dal quale rilevare le collection
var database = clientMongoDB.GetDatabase("Amministrazione");
//Oggetto per la gestione delle collection
var collection = database.GetCollection<BsonDocument>("Dati");
//Rilevo il documento da modificare
var filtro = Builders<BsonDocument>.Filter.Eq("_id", new ObjectId("68a73a8d0d6f07e2909e618c"));
var documentoFile = collection.Find(filtro).FirstOrDefault();
string percorsoNomeFile = "C:\\Varie\\faroBiancoNero.jpg";
// Rilevo Array byte del file
byte[] fileArrayBytes = File.ReadAllBytes(percorsoNomeFile);
//Aggiorno il documento con il nuovo file
var aggiornamento = Builders<BsonDocument>.Update.Set("Contenuto", fileArrayBytes)
.Set("NomeFile", "nuovo_" + Path.GetFileName(percorsoNomeFile));
var options = new UpdateOptions { IsUpsert = false }; //Non crea un nuovo documento se non trova quello da aggiornare
//Aggiorno il documento nella collection
var risultato = collection.UpdateOne(filtro, aggiornamento, options);
//Verifico se è stato aggiornato il documento
if (risultato.ModifiedCount == 0)
{
MessageBox.Show("Nessun documento aggiornato. Verificare l'ID selezionato.");
return;
}
MessageBox.Show("File aggiornato con successo.");
}
catch (MongoCommandException ex)
{
MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Nel caso che vogliamo modificare file con dimensione superiori ai 16 MB, dobbiamo utilizzare la classe GridFSBucket. Di seguito si riporta tale utilizzo per l’evento click del pulsante.
C#
private void BtnAggiornaFileGrandiDimensioni_Click(object sender, EventArgs e)
{
try
{
//Oggetto del client MongoDB
var clientMongoDB = new MongoClient("mongodb://localhost:27017");
//Oggetto per la gestione del database dal quale rilevare le collection
var database = clientMongoDB.GetDatabase("Amministrazione");
//Oggetto per la gestione dei grandi file
var gridFSbucket = new GridFSBucket(database);
//Elimino il file esistente
var filtroElimina = Builders<BsonDocument>.Filter.Eq("filename", "file20Mb.dll");
var documentoFileElimina = database.GetCollection<BsonDocument>("fs.files").Find(filtroElimina).FirstOrDefault();
if (documentoFileElimina != null)
{
var fileIdElimina = documentoFileElimina["_id"].AsObjectId;
gridFSbucket.Delete(fileIdElimina);
}
//Creo un nuovo file
var filePath = "C:\\Varie\\faropuzzle.jpg";
if (!File.Exists(filePath))
{
MessageBox.Show("Il file specificato non esiste.");
return;
}
//Leggo il file e lo converto in array di byte
using (var fileStream = new FileStream(filePath, FileMode.Open))
{
var fileId = gridFSbucket.UploadFromStream(Path.GetFileName(filePath), fileStream);
}
MessageBox.Show("File aggiornato con successo.");
}
catch (MongoCommandException ex)
{
MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Cancellazione
Siamo giunti alla parte conclusiva dell’articolo, ora non resta che vedere una delle varie tecniche per cancellare il valore di un campo del file, ossia eliminare l’array dei byte del file stesso, mantenendo la struttura ed i dati del documento.
La cancellazione del dato in un campo, avviene tramite il metodo “set” della proprietà “Update”, passando come parametro il valore “BsonNull” , dopo aver filtrato il documento in base ad un determinato valore, e consolidando le modifiche tramite il metodo “UpdateOne”, dell’oggetto “IMongoCollection” . Mentre il metodo “UnSet” elimina il campo di un documento, rendendo il documento senza quel determinato campo.
Nel frammento di codice qui di seguito, vedremo come tramite il metodo “Set”, della proprietà “Update”, impostiamo il campo del file, con un valore null.
In un evento click del pulsante, scriviamo il codice che permette di cancellare le informazioni del campo (denominato contenuto) impostando con il valore null.
Passiamo in visualizzazione grafica della nostra form, e facciamo doppio click sul pulsante "BtnElimina", in modo da passare in visualizzazione codice dell'evento click del pulsante.
Di seguito si riporta il codice delle suddette operazioni, con la descrizione dei vari passaggi.
C#
private void BtnEliminaFile_Click(object sender, EventArgs e)
{
try
{
//Oggetto del client MongoDB
var clientMongoDB = new MongoClient("mongodb://localhost:27017");
//Oggetto per la gestione del database dal quale rilevare le collection
var database = clientMongoDB.GetDatabase("Amministrazione");
//Oggetto per la gestione delle collection
var collection = database.GetCollection<BsonDocument>("Dati");
//Rilevo il documento da modificare
var filtro = Builders<BsonDocument>.Filter.Eq("_id", new ObjectId("68a73a4723525c10b1f3f4ea"));
//Aggiorno il documento con zero
var aggiornamento = Builders<BsonDocument>.Update.Set("Contenuto", BsonNull.Value);
var options = new UpdateOptions { IsUpsert = false }; //Non crea un nuovo documento se non trova quello da aggiornare
//Aggiorno il documento nella collection
var risultato = collection.UpdateOne(filtro, aggiornamento, options);
//Verifico se è stato aggiornato il documento
if (risultato.ModifiedCount == 0)
{
MessageBox.Show("Nessun documento aggiornato. Verificare l'ID selezionato.");
return;
}
MessageBox.Show("File aggiornato con successo.");
}
catch (MongoCommandException ex)
{
MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Conclusioni
L’articolo ha voluto offrire al lettore una panoramica sull’utilizzo della gestione dei file con il database MongoDB Community, affrontando le varie operazioni per comprendere come lavorare sui documenti con i relativi file. La gestione dei file con questo database è un elemento chiave, come lo è per tutti quei progetti di gestione documentale. La flessibilità di questo database di tipo NoSQl, offre al programmatore semplicità nel realizzare nell’immediato applicativi di un certo livello.