🚀 Nuova versione beta disponibile! Feedback o problemi? Contattaci

Serializzazione in C#

Codegrind Team•Aug 28 2024

La serializzazione è il processo di conversione di un oggetto in un formato che può essere facilmente memorizzato o trasmesso e successivamente ricostruito nella sua forma originale. In C#, la serializzazione è spesso utilizzata per salvare lo stato di un oggetto su disco, trasmettere oggetti attraverso la rete, o convertire oggetti in formati leggibili come JSON o XML. In questa guida esploreremo le tecniche di serializzazione disponibili in C#, inclusa la serializzazione JSON, XML, binaria, e le best practices per implementarla in modo sicuro ed efficiente.

Cos’è la Serializzazione?

La serializzazione è il processo di conversione di un oggetto in un formato seriale, che può essere memorizzato o trasmesso. Il processo inverso, chiamato deserializzazione, ricostruisce l’oggetto originale dal formato seriale.

Formati Comuni di Serializzazione

  1. JSON (JavaScript Object Notation): Formato leggero, leggibile dall’uomo, ampiamente utilizzato per la trasmissione di dati tra client e server.
  2. XML (Extensible Markup Language): Formato di markup ampiamente utilizzato per l’interoperabilità tra sistemi diversi.
  3. Serializzazione Binaria: Formato compatto, non leggibile dall’uomo, utilizzato per la persistenza di oggetti o la trasmissione di dati binari.

Serializzazione JSON

La serializzazione JSON è uno dei metodi più comuni per convertire oggetti in formato JSON. In C#, la libreria System.Text.Json fornisce strumenti potenti per la serializzazione e deserializzazione JSON.

Esempio di Serializzazione JSON

using System.Text.Json;

public class Persona
{
    public string Nome { get; set; }
    public int Età { get; set; }
}

public static void Main()
{
    Persona persona = new Persona { Nome = "Mario", Età = 30 };
    string json = JsonSerializer.Serialize(persona);
    Console.WriteLine(json);  // Output: {"Nome":"Mario","Età":30}
}

Esempio di Deserializzazione JSON

string json = "{\"Nome\":\"Mario\",\"Età\":30}";
Persona persona = JsonSerializer.Deserialize<Persona>(json);
Console.WriteLine($"Nome: {persona.Nome}, Età: {persona.Età}");  // Output: Nome: Mario, Età: 30

Opzioni Avanzate per la Serializzazione JSON

JsonSerializerOptions consente di configurare la serializzazione, come l’uso di camelCase per i nomi delle proprietà, l’ignorare i valori null, e così via.

var options = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};

string json = JsonSerializer.Serialize(persona, options);

Serializzazione XML

La serializzazione XML è ampiamente utilizzata per scambiare dati tra sistemi diversi, grazie alla sua leggibilità e flessibilità.

Esempio di Serializzazione XML

using System.Xml.Serialization;
using System.IO;

public class Persona
{
    public string Nome { get; set; }
    public int Età { get; set; }
}

public static void Main()
{
    Persona persona = new Persona { Nome = "Mario", Età = 30 };
    XmlSerializer serializer = new XmlSerializer(typeof(Persona));

    using StringWriter stringWriter = new StringWriter();
    serializer.Serialize(stringWriter, persona);
    Console.WriteLine(stringWriter.ToString());
    // Output: <Persona><Nome>Mario</Nome><Età>30</Età></Persona>
}

Esempio di Deserializzazione XML

string xml = "<Persona><Nome>Mario</Nome><Età>30</Età></Persona>";
XmlSerializer serializer = new XmlSerializer(typeof(Persona));

using StringReader stringReader = new StringReader(xml);
Persona persona = (Persona)serializer.Deserialize(stringReader);
Console.WriteLine($"Nome: {persona.Nome}, Età: {persona.Età}");  // Output: Nome: Mario, Età: 30

Personalizzazione della Serializzazione XML

È possibile personalizzare la serializzazione XML utilizzando attributi come [XmlElement], [XmlAttribute], [XmlIgnore], e così via.

public class Persona
{
    [XmlAttribute]
    public string Nome { get; set; }

    [XmlElement]
    public int Età { get; set; }

    [XmlIgnore]
    public string Password { get; set; }
}

Serializzazione Binaria

La serializzazione binaria è utilizzata per convertire oggetti in un formato binario compatto. Questo tipo di serializzazione è utile quando la dimensione dei dati è critica, ma non è leggibile dall’uomo e può presentare problemi di compatibilità tra versioni diverse.

Esempio di Serializzazione Binaria

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

[Serializable]
public class Persona
{
    public string Nome { get; set; }
    public int Età { get; set; }
}

public static void Main()
{
    Persona persona = new Persona { Nome = "Mario", Età = 30 };
    BinaryFormatter formatter = new BinaryFormatter();

    using FileStream stream = new FileStream("persona.dat", FileMode.Create);
    formatter.Serialize(stream, persona);
}

Esempio di Deserializzazione Binaria

using FileStream stream = new FileStream("persona.dat", FileMode.Open);
Persona persona = (Persona)formatter.Deserialize(stream);
Console.WriteLine($"Nome: {persona.Nome}, Età: {persona.Età}");  // Output: Nome: Mario, Età: 30

Serializzazione Personalizzata

In alcune situazioni, potresti voler controllare esattamente come un oggetto viene serializzato e deserializzato. C# ti permette di implementare la serializzazione personalizzata implementando l’interfaccia ISerializable.

Esempio di Serializzazione Personalizzata

[Serializable]
public class Persona : ISerializable
{
    public string Nome { get; set; }
    public int Età { get; set; }

    // Costruttore normale
    public Persona() { }

    // Costruttore per la deserializzazione
    protected Persona(SerializationInfo info, StreamingContext context)
    {
        Nome = info.GetString("Nome");
        Età = info.GetInt32("Età");
    }

    // Metodo per la serializzazione
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("Nome", Nome);
        info.AddValue("Età", Età);
    }
}

Best Practices per la Serializzazione

1. Gestire la Versione degli Oggetti

Quando aggiorni la definizione di una classe, considera la compatibilità con le versioni precedenti, soprattutto se gli oggetti serializzati potrebbero essere deserializzati con una nuova versione del software.

2. Considerare la Sicurezza

La deserializzazione può essere vulnerabile a diversi attacchi, come l’inserimento di dati malevoli. Evita di deserializzare dati non fidati senza una corretta validazione.

3. Utilizzare Attributi per il Controllo Flessibile

Attributi come [JsonProperty], [XmlElement], e [NonSerialized] ti permettono di controllare quali membri della classe devono essere serializzati o ignorati.

4. Mantenere la Coerenza dei Dati

Assicurati che gli oggetti siano coerenti e pronti per la serializzazione. Ad esempio, evita di serializzare oggetti in stati incoerenti o parziali.

5. Preferire Formati di Serializzazione Leggibili

Quando possibile, preferisci formati di serializzazione leggibili come JSON o XML, soprattutto per dati che devono essere condivisi o memorizzati a lungo termine.

Casi d’Uso Comuni della Serializzazione

1. Persistenza dei Dati

Salvare lo stato di un oggetto su disco, in un database, o in altri sistemi di archiviazione per un successivo recupero.

2. Trasmissione di Dati su Rete

Trasmettere oggetti attraverso la rete, come nelle API RESTful che utilizzano JSON per scambiare dati tra client e server.

3. Caching

Memorizzare lo stato di un oggetto in memoria o su disco per un recupero rapido in un secondo momento, evitando di ricostruire l’oggetto da zero.

4. Clone Profondo

Creare una copia profonda di un oggetto serializzando e deserializzando, garantendo che tutte le referenze

vengano copiate.

public static T Clone<T>(T oggetto)
{
    using MemoryStream ms = new MemoryStream();
    BinaryFormatter formatter = new BinaryFormatter();
    formatter.Serialize(ms, oggetto);
    ms.Position = 0;
    return (T)formatter.Deserialize(ms);
}

Conclusione

La serializzazione in C# è uno strumento potente per la gestione e la trasmissione dei dati, permettendo di convertire oggetti in formati leggibili e non leggibili, per poi ripristinarli al loro stato originale. Comprendere le diverse tecniche di serializzazione disponibili e come applicarle correttamente ti permetterà di sviluppare applicazioni più robuste, sicure e scalabili. Seguendo le best practices, puoi garantire che i tuoi dati siano sempre gestiti in modo coerente ed efficiente, indipendentemente dal formato di serializzazione scelto.