Passa ai contenuti principali

VB for Dummies: La serializzazione – parte 1

Questo post è dedicato alla serializzazione e a come sia possibile sfruttarla in Visual Basic.

Partiamo con una definizione di serializzazione presa da Wikipedia:

In informatica, la serializzazione è un processo per salvare un oggetto in un supporto di memorizzazione lineare (ad esempio, un file o un'area di memoria), o per trasmetterlo su una connessione di rete. La serializzazione può essere in forma binaria o può utilizzare codifiche testuali (ad esempio il formato XML) direttamente leggibili dagli esseri umani. Lo scopo della serializzazione è di trasmettere l'intero stato dell'oggetto in modo che esso possa essere successivamente ricreato nello stesso identico stato dal processo inverso, chiamato deserializzazione.

In sostanza si tratta di poter “scrivere” l’oggetto in un formato standard per poter essere “ricostruito” in un momento successivo, in un’altra applicazione o, addirittura in altri linguaggi e piattaforme di sviluppo.

In questo post tralasceremo la serializzazione binaria e ci occuperemo delle tre principali modalità di serializzazione testuali utilizzate: XML, SOAP e JSON.

Poichè serializzare significa prendere un nostro oggetto e “trasformarlo” in una stringa (in parole veramente molto semplici) con un determinato formato, dobbiamo partire da un oggetto e per fare questo creiamo una classe fattura (molto semplice!!) che utilizzeremo nei nostri esperimenti:

image

Le classi in gioco sono, evidentemente molto semplici e servono esclusivamente da esempio senza avere la pretesa di essere esaustive.

La proprietà Totale della classe Fattura è di tipo ReadOnly (così come Totale e Totale Ivato del Dettaglio Fattura) e vedremo come questo influenza la serializzazione.

In dettagli le classi sono le seguenti:

  1. Imports System.Xml.Serialization
  2.  
  3. Public Class Fattura
  4.     Public Sub New()
  5.         Dettagli = New List(Of DettaglioFattura)
  6.     End Sub
  7.  
  8.     Public Property DataEmissione As DateTime
  9.     Public Property Cliente As Cliente
  10.     Public Property NumeroDocumento As String
  11.     Public Property Dettagli As List(Of DettaglioFattura)
  12.     Public Property Stato As StatoFattura
  13.  
  14.     Public ReadOnly Property Totale As Decimal
  15.         Get
  16.             If Dettagli Is Nothing Then
  17.                 Return 0
  18.             Else
  19.                 Return Dettagli.Sum(Function(d) d.TotaleIvato)
  20.             End If
  21.         End Get
  22.     End Property
  23.  
  24. End Class

 

  1. Public Class DettaglioFattura
  2.  
  3.     Public Property Descrizione As String
  4.     Public Property Codice As String
  5.     Public Property Quantita As Integer
  6.     Public Property PrezzoUnitario As Decimal
  7.     Public Property Iva As Decimal
  8.  
  9.     Public ReadOnly Property Totale As Decimal
  10.         Get
  11.             Return Quantita * PrezzoUnitario
  12.         End Get
  13.     End Property
  14.  
  15.     Public ReadOnly Property TotaleIvato As Decimal
  16.         Get
  17.             Return Totale * (1 + Iva)
  18.         End Get
  19.     End Property
  20. End Class

 

  1. Public Class Cliente
  2.  
  3.     Public Property Denominazione As String
  4.     Public Property CodiceFiscale As String
  5.     Public Property PartitaIVA As String
  6.  
  7. End Class

 

  1. Public Enum StatoFattura
  2.     DaPagare
  3.     Pagata
  4.     Annullata
  5. End Enum

 

Serializzazione in XML

Il primo tipo di serializzazione che vedremo è quello XML, cioè vedremo come “scrivere” le istanze della nostra classe fattura in formato XML.

Per poter serializzare una nostra classe in formato XML, la classe stessa deve essere serializzabile, ovvero composta da proprietà (i metodi non vengono serializzati) serializzabili. Se, ad esempio la nostra classe contiene una proprietà di un tipo .NET non serializzabile l’intera classe non è serializzabile.

Il processo di serializzazione si basa sull’utilizzo della classe XmlSerializer e di un oggetto che serva da flusso in cui scrivere l’XML risultante (un XmlWriter, un TextWriter, uno Stream).

In particolare il costruttore dell’XmlSerializer prevede che venga dichiarata per quale classe stiamo costruendo il serializzatore, quindi possiamo utilizzare il metodo Serialize() per scrivere l’XML risultatnte nello stream o nel writer opportuno. La seguente funzione restituisce la stringa XML utilizzando uno StringWriter:

  1. Public Shared Function SerializzaXML(ByVal fattura As Fattura) As String
  2.     If fattura Is Nothing Then Throw New ArgumentNullException("Fattura")
  3.     Dim strXml As String = Nothing
  4.     Dim writer As New XmlSerializer(GetType(Fattura))
  5.     Using strWriter As New StringWriter()
  6.         writer.Serialize(strWriter, fattura)
  7.         strXml = strWriter.ToString()
  8.     End Using
  9.     Return strXml
  10. End Function

La seguente figura mostra la serializzazione di una fattura di prova:

image

Come possiamo osservare, tutte le proprietà della nostra classe vengono riportate all’interno dell’XML frutto della serializzazione. Ogni proprietà diventa un tag XML con il nome pari al nome della proprietà. Infine lo stato della fattura (definito come un’enumerazione) viene scritto come una stringa esattamente pari al valore dell’enumerazione impostato. A livello di codice, nel momento in cui viene eseguito il Serialize, vengono richiamati tutti i Get delle proprietà lettura/scrittura della classe (nel caso precedente non la proprietà Totale).

Di fatto, il comportamento visto in precedenza, è quello di default ma abbiamo la possibilità di intervenire per modificare il risultato dell’XML e lo possiamo fare utilizzando degli appositi attributi copntenuti nel namespace System.Xml.Serialization.

Se vogliamo, ad esempio, che una o più proprietà della nostra classe non finiscano all’interno dell’XML, possiamo utilizzare l’attributo XmlIgnoreAttribute decorando proprio la proprietà (o l’attributo) che non vogliamo finisca all’interno dell’XML.

Ad esempio, supponiamo di avere una proprietà della nostra fattura, chiamata Id, che non vogliamo serializzare. Potremo scrivere:

  1. <XmlIgnore()>
  2. Public Property Id As Integer?

In questo modo l’XML che si ottiene non ha il tag <Id>.

In maniera analoga, se vogliamo che una nostra proprietà non diventi un tag XML ma un attributo del tag Fattura, possiamo utilizzare l’attributo XmlAttribute indicando, eventualmente, il nome dell’attributo (altrimenti viene utilizzato il nome della proprietà):

  1. <XmlAttribute()>
  2. Public Property NumeroDocumento As String

E se volessimo che un tag XML non abbia il nome della proprietà ma un altro nome, allora potremmo utilizzare l’attributo XmlElement indicamndo il nome del tag:

  1. <XmlElement("Emissione")>
  2. Public Property DataEmissione As DateTime

Gli attributi contenuti nel namespace System.Serialization ci consentono, dunque di modificare il risultato della serializzazione a partire da quello di default.

Tutto ciò è utilissimo, non tanto quando siamo noi a gestire il gioco e definire lo schema dell’XML ma quando ci viene assegnato uno schema prestabilito e vogliamo creare un mapping a noi comodo con una classe da noi creata.

Vediamo, ora, la deserializzazione, ovvero il processo inverso della serializzazione, cioè quella procedura che ci permette di creare un oggetto a partire dall’XML.

L’XmlSerializer ci consente di deserializzare una stringa XML in un oggetto. In questo caso, anzichè un writer come supporto, dobbiamo utilizzare un reader:

  1. Public Shared Function DeserializzaXML(ByVal strFattura As String) As Fattura
  2.     Dim retObj As Fattura = Nothing
  3.     Dim reader = New XmlSerializer(GetType(Fattura))
  4.     Dim strReader = New StringReader(strFattura)
  5.     Try
  6.         retObj = CType(reader.Deserialize(strReader), Fattura)
  7.     Catch ex As Exception
  8.         Throw
  9.     End Try
  10.     Return retObj
  11. End Function

Ovviamente, se l’XML non è aderente allo schema, otteniamo un’eccezione nel momento in cui deserializziamo.

Ma cosa succede quando viene eseguite la deserializzazione?

Nel momento in cui viene richiamato il metodo Deserialize, viene istanziato l’oggetto di classe Fattiura (viene chiamato il costruttore) e, quindi, in sequenza vengono richiamati i set delle proprietà trovate all’interno dell’XML.

Per questo motivo, se non inseriamo un tag XML all’interno del file serializzato, la proprietà risultante conterrà il valore di default. Attenzione, quindi, a che le proprietà abbiano un valore di default coerente.

Nel prossimo post vedremo brevemente la serializzazione SOAP e, soprattutto, la serializzazione JSON.

Stay Tuned!!!!


 

Commenti

Post popolari in questo blog

VB.NET: Convertire un file DOC in RTF e PDF con office interop

In questo post vorrei proporvi del codice per poter convertire un file .doc in un file .rtf oppure .pdf utilizzando le API di interoperabilità di Office.Creeremo una classe, DocConverter, che esporrà le due funzionalità sopra citate.Cominciamo con il prevedere un attributo privato della classe che rappresenterà l’applicazione Word che utilizzeremo per la conversione. Creeremo l’istanza dell’attributo privato all’interno del costruttore della classe:PublicSubNew()
IfNot CreateWordApp() Then
ThrowNew ApplicationException("Assembly di interoperabilità con Office non trovato!")
EndIf
EndSub
Private _wordApp As Word.ApplicationClass
ProtectedFunction CreateWordApp() AsBoolean
Dim retval = True
Try
_wordApp = New Word.ApplicationClass()
_wordApp.Visible = False
Catch ex As System.Exception
_wordApp = Nothing
retval = False
EndTry
Return retval
EndFunction

La conversione del file doc sarà effettuata aprendo il file stesso ed eseguendo un’operazione di SaveAs:

Pr…

Cambiare la lingua di Visual Studio 2008

Oggi ho avuto qualche problema installando Windows Mobile 6 Professional SDK Refresh e Windows Mobile 6 Standard SDK Refresh.Scaricati i file di installazione e installati, ho provato a creare un progetto di tipo Windows Mobile 6.0 e mi sono beccato questo errore:Dopo qualche smanettamento abbiamo scoperto (e ringrazio il mitico Matteo per l’aiuto) che il mio Visual Studio 2008, pur essendo in Inglese (prova ne era il fatto che gli hotfix e la SP installata erano nella lingua di Albione) aveva come lingua impostata quella del sistema operativo (italiano).Ovviamente, non avrebbe mai potuto trovare la cartella 1040 (italiano) visto che l’installazione dell’SDK aveva supposto che la lingua del Visual Studio fosse Inglese (1033).La soluzione del problema è duplice:1) Duplicate la cartella 1033 presente nel percorso evidenziato dall’errore e la rinominate 10402) cambiate la lingua di Visual Studio.Per questa ultima eventualità basta andare nel menù Strumenti/Opzioni:e cambiare il linguaggi…

Tascam DR-05 registratore digitale per tutti

Diverso tempo fa ho acquistato il registratore digitale Tascam DR-05 e, ora, dopo diversi mesi di utilizzo, posso dire la mia a proposito.

Si tratta di un ottimo registratore digitale con microfono stereo che permette di ottenere registrazioni di ottima qualitaà anche in ambienti non perfetti dal punto di vista acustico.

Interessante la possibilità di utilizzare un cavalletto di piccole dimensioni come HAMA Mini treppiede o Mini Cavalletto Universale per tenere il microfono sollevato dal tavolo in fase di registrazione grazie allàattacco universale per macchina fotografica che il microfono ha nella parte inferiore.

Da segnalare anche il menu’ ben fatto e la possibilita’ di utilizzare una scheda SD esterna per memorizzare i file audio. Anche a livello di consumo batterie non e’ niente male. Consiglio l’uso delle alcaline non ricaricabili.

Il mio utilizzo e’ stato prettamente di registrazione di podcast vocali (no musica) ma le recensioni confermano che se la cava egregiamente con la mu…