Salvare una classe .NET su file con la serializzazione

di Cristian Civera, in UserScript, ASP.NET, C#,

Il .NET framework mette a disposizione delle nuove incredibili funzionalità che ci permettono di rendere persistente una nostra classe e poterla trasportare tramite cavo o salvarla su disco. Questo meccanismo prende il nome di serializzazione ed è lo stesso sfruttato dai web services (trasformazione in formato XML), da Remoting (XML e binario), dal ViewState (binario, codificato base64), ma possiamo usarlo anche noi.
Faremo un esempio che salva una nostra classe su disco per poi andarla a recuperare in un secondo momento.
Vi sono due modi per serializzare una classe. Usare XmlSerializer (namespace System.Xml.Serialization) o usare i formatters, classi che implementano l'interfaccia IRemotingFormatter (namespace System.Runtime.Remoting.Messaging).
Del primo metodo si è parlato in quest'articolo (https://www.aspitalia.com/articoli/aspplus/webserviceXML.aspx); noi useremo il secondo che è molto più potente. I formatters sono in grado di serializzare anche membri privati e sono abbastanza intelligenti da rimuovere informazioni ridondanti.
Useremo per l'esempio il SoapFormatter (namespace e assembly System.Runtime.Serialization.Formatters.Soap) così da vedere cosa ha salvato su disco in un formato a noi comprensibile.
Scriviamo una classe che conterrà le nostre informazioni

[Serializable()]
public class SampleClass
{
  public string Description;

  [NonSerialized()]
  public DateTime Date = DateTime.MinValue;

}

L'attributo Serializable è indispensabile per rendere la nostra classe serializzabile. Non serve altro che assicurarsi che anche i membri referenziati in essa presentino questo attributo. L'attributo NonSerialized, applicabile solo a campi, indica che quel membro non andrà serializzato. Lo usiamo per dimostrare cosa salva il formatter.
Creiamo una textbox di id 'description', due pulsanti, uno di load e un altro di save.
Ecco come salviamo la classe:

private void btnSave_Click(object sender, System.EventArgs e)
  {
  // Creo la classe con dentro le informazioni
  SampleClass sc = new SampleClass();
  sc.Description = description.Text;
  sc.Date = DateTime.Now;

  Response.Write(String.Format("Data salvataggio: {0}", sc.Date));

  // Creo il formatter adeguato
  SoapFormatter formatter = new SoapFormatter();

  // Apro in scrittura un nuovo file o lo sovrascrive
  using (FileStream file = new FileStream(filename, FileMode.Create, FileAccess.Write))
  {
    // Effettuo la serializzazione
    formatter.Serialize(file, sc);
    Response.Write(String.Format("<br>Classe salvata su {0}!",
    filename));
  }
  }

Ricordatevi di dare accesso in scrittura sulla cartella dove provate l'esempio.
Per il caricamento invece useremo:

  private void btnLoad_Click(object sender, System.EventArgs e)
  {
  SampleClass sc = null;
  if (File.Exists(filename))
  {
    // Creo il formatter adeguato
    SoapFormatter formatter = new SoapFormatter();

    // Apro in lettura il file
    using (FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read))
    {
    sc = formatter.Deserialize(file) as SampleClass;
    }
  }
  if (sc == null)
    sc = new SampleClass();

  description.Text = sc.Description;

  Response.Write(String.Format("Data salvataggio dei dati caricati: {0}", sc.Date));
  }

Prendete l'esempio allegato. Scrivete del testo, salvate e chiudete la pagina. Andate a vedere file.txt e vedrete un file in formato XML (o meglio SOAP) con un namespace indicante l'assembly che contiene la classe, un nodo description e, come volevamo noi, senza la data, poiché marcata con l'attributo NonSerialized.
Ora riaprite la pagina e premete Carica. La descrizione verrà caricata correttamente, mentre la data sarà quella di default: DateTime.MinSize.

In poche righe con la serializzazione possiamo salvare classi intere in modo molto semplice e veloce. Direi che è molto meglio dei vecchi files .ini o di files in formato XML ma che richiedono il salvataggio e il recupero di ogni singolo nodo manualmente.
Prestate attenzione con il versioning dell'assembly, che come si vede dal file xml, se usate versioni diverse non troverà il tipo di classe da deserializzare. Per rendere serializzabile una classe si può anche implementare l'interfaccia ISerializable che permette un controllo maggiore dei dati.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi