Home

SOAP Serialization

 

Object Serialization and De-Serialization

 
 

Introduction

Consider the following program:

Serialization

Imports System.IO

Public Class Exercise

    Private Sub btnWrite_Click(ByVal sender As System.Object, _
                               ByVal e As System.EventArgs) Handles btnWrite.Click
        Dim Make As String = txtMake.Text
        Dim Model As String = txtModel.Text
        Dim Year As Integer = CInt(txtYear.Text)
        Dim CarColor As Integer = cbxColors.SelectedIndex

        Dim stmCar As FileStream = New FileStream("Car1.car", FileMode.Create)
        Dim bnwCar As BinaryWriter = New BinaryWriter(stmCar)

        Try
            bnwCar.Write(Make)
            bnwCar.Write(Model)
            bnwCar.Write(Year)
            bnwCar.Write(CarColor)
        Finally
            bnwCar.Close()
            stmCar.Close()
        End Try
    End Sub
End Class

Here is an example of running the program:

This is an example of the techniques used in file processing to save individual data of primitive types:

Saving the variables in a method

The values can be retrieved with the following code:

Imports System.IO

Public Class Exercise

    Private Sub btnWrite_Click(ByVal sender As System.Object, _
                               ByVal e As System.EventArgs) Handles btnWrite.Click
        Dim Make As String = txtMake.Text
        Dim Model As String = txtModel.Text
        Dim Year As Integer = CInt(txtYear.Text)
        Dim CarColor As Integer = cbxColors.SelectedIndex

        Dim stmCar As FileStream = New FileStream("Car1.car", FileMode.Create)
        Dim bnwCar As BinaryWriter = New BinaryWriter(stmCar)

        Try
            bnwCar.Write(Make)
            bnwCar.Write(Model)
            bnwCar.Write(Year)
            bnwCar.Write(CarColor)
        Finally
            bnwCar.Close()
            stmCar.Close()
        End Try
    End Sub

    Private Sub btnRead_Click(ByVal sender As Object, _
                              ByVal e As System.EventArgs) Handles btnRead.Click
        Dim stmCar As FileStream = New FileStream("Car1.car", FileMode.Open)
        Dim bnrCar As BinaryReader = New BinaryReader(stmCar)

        Try
            txtMake.Text = bnrCar.ReadString()
            txtModel.Text = bnrCar.ReadString()
            txtYear.Text = bnrCar.ReadUInt32().ToString()
            cbxColors.SelectedIndex = bnrCar.ReadInt32()
        Finally
            bnrCar.Close()
            stmCar.Close()
        End Try
    End Sub
End Class

In the same way, you can save the individual fields of a class or you can retrieve the individual fields of a car:

Saving the individual parts of an object

Here is an example:

Class: Car.vb
Public Class Car
    Public Make As String
    Public Model As String
    Public Year As Integer
    Public Color As Integer
End Class
Imports System.IO

Public Class Exercise

    Private Sub btnWrite_Click(ByVal sender As System.Object, _
                               ByVal e As System.EventArgs) Handles btnWrite.Click
        Dim Vehicle As Car = New Car()

        Vehicle.Make = txtMake.Text
        Vehicle.Model = txtModel.Text
        Vehicle.Year = CInt(txtYear.Text)
        Vehicle.Color = cbxColors.SelectedIndex

        Dim stmCar As FileStream = New FileStream("Car2.car", FileMode.Create)
        Dim bnwCar As BinaryWriter = New BinaryWriter(stmCar)

        Try
            bnwCar.Write(Vehicle.Make)
            bnwCar.Write(Vehicle.Model)
            bnwCar.Write(Vehicle.Year)
            bnwCar.Write(Vehicle.Color)
        Finally
            bnwCar.Close()
            stmCar.Close()
        End Try
    End Sub

    Private Sub btnRead_Click(ByVal sender As Object, _
                              ByVal e As System.EventArgs) Handles btnRead.Click
        Dim stmCar As FileStream = New FileStream("Car2.car", FileMode.Open)
        Dim bnrCar As BinaryReader = New BinaryReader(stmCar)

        Try
            Dim Vehicle As Car = New Car()

            Vehicle.Make = bnrCar.ReadString()
            Vehicle.Model = bnrCar.ReadString()
            Vehicle.Year = bnrCar.ReadUInt32()
            Vehicle.Color = bnrCar.ReadInt32()

            txtMake.Text = Vehicle.Make
            txtModel.Text = Vehicle.Model
            txtYear.Text = Vehicle.Year
            cbxColors.SelectedIndex = Vehicle.Color
        Finally
            bnrCar.Close()
            stmCar.Close()
        End Try
    End Sub
End Class

When it comes to a class, the problem with saving individual fields is that you could forget to save one of the fields. For example, considering a Car class, if you don't save the Make information of a Car object and retrieve or open the saved object on another computer, the receiving user would miss some information and the car cannot be completely identifiable. An alternative is to save the whole Car object.

Object serialization consists of saving a whole object as one instead of its individual fields:

Serialization

In other words, a variable declared from a class can be saved to a stream and then the saved object can be retrieved later or on another computer. The .NET Framework supports two types of object serialization: binary and SOAP.

SOAP Serialization

 

Introduction to SOAP Serialization

The .NET Framework supports a technique of serialization referred to as SOAP (which stands for Simple Object Access Protocol). This technique is a related to XML but, although we haven't studied XML, you don't need to know anything about it to use SOAP serialization.

Practical Learning: Introducing SOAP Serialization

  1. Start a new Windows Application named Loan1
  2. In the Solution Explorer, right-click Form1.vb and click Rename
  3. Type LoanPreparation.vb and press Enter
  4. Design the form as followed:
     
    Watts A Loan
    Control Name Text Additional Properties
    GroupBox GroupBox   Loan Identification  
    Label Label   Prepared &By:  
    TextBox TextBox txtEmployeeName    
    Label Label   Customer First Name:  
    TextBox TextBox txtCustomerFirstName    
    Label Label   Last Name:  
    TextBox TextBox txtCustomerLastName    
    GroupBox GroupBox   Loan Preparation  
    Label Label   Principal:  
    TextBox TextBox txtPrincipal 0.00 TextAlign: Right
    Label Label   Interest Rate:  
    TextBox TextBox txtInterestRate 8.25 TextAlign: Right
    Label Label   %  
    Label Label   Periods:  
    TextBox TextBox txtPeriods 1 TextAlign: Text
    ComboBox cbxPeriods Months Items:
    Years
    Months
    Days
    GroupBox GroupBox   Results  
    Button Button btnCalculate Calculate  
    Label Label   Interest Earned:  
    TextBox TextBox txtInterestEarned 0.00 TextAlign: Right
    ReadOnly: True
    Label Label   Amount Earned:  
    TextBox TextBox txtFutureValue 0.00 TextAlign: Right
    ReadOnly: True
    GroupBox GroupBox   File Processing  
    Label Label   Loan ID:  
    TextBox TextBox txtSave    
    Button Button &Save btnSave  
    Label Label   Loan ID:  
    TextBox TextBox txtOpen    
    Button Button &Open btnOpen  
    Button Button btnClose Close  
  5. Right-click the form and click View Code
  6. In the Class Name combo box, select txtCustomerLastName
  7. In the Method Name combo box, select Leave and implement the event as follows:
     
    Private Sub txtCustomerLastName_Leave(ByVal sender As Object, _
                                              ByVal e As System.EventArgs) _
                                              Handles txtCustomerLastName.Leave
            Dim Initials As String = "00"
            Dim FirstName As String = txtCustomerFirstName.Text
            Dim LastName As String = txtCustomerLastName.Text
    
            If LastName.Length = 0 Then
                MsgBox("You must enter a last name")
                txtCustomerLastName.Focus()
                Exit Sub
            End If
    
            If FirstName.Length = 0 Then
                Initials = LastName.Substring(0, 1) & "1"
            Else
                Initials = FirstName.Substring(0, 1) & LastName.Substring(0, 1)
            End If
    
            txtSave.Text = Initials
    End Sub
  8. In the Class Name combo box, select btnCalculate
  9. In the Method Name combo box, select Click and implement the event as follows:
     
    Private Sub btnCalculate_Click(ByVal sender As Object, _
                                       ByVal e As System.EventArgs) _
                                       Handles btnCalculate.Click
            Dim Principal As Double
            Dim InterestRate As Double
            Dim InterestEarned As Double
            Dim FutureValue As Double
            Dim Periods As Double
    
            ' Retrieve the value of the principal
            Try
                Principal = CDbl(txtPrincipal.Text)
            Catch ex As FormatException
                MsgBox("The value you entered for the principal " & _
                                "is not valid.\nPlease try again")
            End Try
    
            ' Retrieve the interest rate
            Try
                InterestRate = CDbl(txtInterestRate.Text) / 100
            Catch ex As FormatException
                MsgBox("The value you entered for the interest " & _
                                "rate is not valid\nPlease try again")
            End Try
    
            ' Get the number of periods
            Try
                If cbxPeriods.SelectedIndex = 0 Then ' Years
                    Periods = CDbl(txtPeriods.Text)
                ElseIf cbxPeriods.SelectedIndex = 1 Then ' Months
                    Periods = CDbl(txtPeriods.Text) / 12
                Else ' if cbxPeriods.SelectedIndex = 2)  Days
                    Periods = CDbl(txtPeriods.Text) / 360
                End If
    
            Catch ex As FormatException
                MsgBox("The value you entered for the number " & _
                                "of periods is not valid\nPlease try again")
            End Try
    
            Dim InterestRatePeriods As Double = InterestRate * Periods
            Dim InterestPlus1 As Double = InterestRatePeriods + 1
            FutureValue = Principal * InterestPlus1
            InterestEarned = FutureValue - Principal
    
            txtInterestEarned.Text = FormatNumber(InterestEarned)
            txtFutureValue.Text = FormatNumber(FutureValue)
    End Sub
  10. Execute the application to make sure it is fine
  11. After using it, close the form and return to your programming environment

Serialization With SOAP

To serialize an object using SOAP, you follow the same steps we reviewed for the binary serialization with one addition: you must add a certain reference.

When creating the class whose objects would be serialized, mark it with the <Serializable> attribute. Here is an example:

<Serializable()> Public Class Car
    Public Make As String
    Public Model As String
    Public Year As Integer
    Public Color As Integer
End Class

To support SOAP serialization, the .NET Framework provides the SoapFormatter class. This class is defined in the System.Runtime.Serialization.Formatters.Soap namespace that is part of the System.Runtime.Serialization.Formatters.Soap.dll assembly. In order to use The SoapFormatter class, you must reference this assembly. Then, you can create an object and initialize it as you see fit. Before saving it, as always, create a Stream-based object that would indicate the name (and location) of the file and the type of action to perform. Then, declare a SoapFormatter dim as iable using its default constructor. To actually save the object, call the Serialize() method of this class. This method uses the same syntax as that of the BinaryFormatter class: it takes two arguments. The first is a Stream-based object. The second is the object that needs to be serialized.

Practical Learning: Serializing With SOAP

  1. To create a new class, on the main menu, click Project -> Add Class...
  2. Set the Name to LoanInformation and click Add
  3. Change the file as follows:
     
    <Serializable()> Public Class LoanInformation
        Public EmployeeName As String
        Public CustomerFirstName As String
        Public CustomerLastName As String
        Public Principal As Double
        Public InterestRate As Double
        Public Periods As Double
        Public PeriodType As Integer
    End Class
  4. To add SOAP support to your project, on the main menu, click Project -> Add Reference...
  5. In the Add Reference dialog box and in the .NET tab, scroll down and select System.Runtime.Serialization.Formatters.Soap:
     
    Adding a reference to the System.Runtime.Serialization.Formatters.Soap.dll assembly
  6. Click OK
  7. Access the LoanPreparation.vb code file
  8. In the top section of the form, type the following:
     
    Imports System.IO
    Imports System.Runtime.Serialization.Formatters.Soap
    
    Public Class LoanPreparation
  9. In the Class Name combo box, select btnSave
  10. In the Method Name combo box, select Click and implement the event as follows:
     
    Private Sub btnSave_Click(ByVal sender As Object, _
                                  ByVal e As System.EventArgs) _
                                  Handles btnSave.Click
            If txtSave.Text.Length = 0 Then
                MsgBox("Please enter the customer " & _
           "initials or a name for the loan")
                txtSave.Focus()
                Exit Sub
            End If
    
            Dim infLoan As LoanInformation = New LoanInformation
    
            infLoan.EmployeeName = txtEmployeeName.Text
            infLoan.CustomerFirstName = txtCustomerFirstName.Text
            infLoan.CustomerLastName = txtCustomerLastName.Text
            infLoan.Principal = CDbl(txtPrincipal.Text)
            infLoan.InterestRate = CDbl(txtInterestRate.Text)
            infLoan.Periods = CDbl(txtPeriods.Text)
            infLoan.PeriodType = cbxPeriods.SelectedIndex
    
            Dim stmLoan As FileStream = New FileStream(txtSave.Text, _
                                                       FileMode.Create, _
                                                       FileAccess.Write)
            Dim sfmLoan As SoapFormatter = New SoapFormatter
    
            Try
                sfmLoan.Serialize(stmLoan, infLoan)
    
                txtEmployeeName.Text = ""
                txtCustomerFirstName.Text = ""
                txtCustomerLastName.Text = ""
                txtPrincipal.Text = "0.00"
                txtInterestRate.Text = "0.00"
                txtPeriods.Text = "0"
                cbxPeriods.SelectedIndex = 0
                txtFutureValue.Text = "0.00"
                txtInterestEarned.Text = "0.00"
                txtSave.Text = ""
                txtOpen.Text = ""
                txtEmployeeName.Focus()
            Finally
                stmLoan.Close()
            End Try
    End Sub
  11. Press Ctrl + F5 to execute the application
  12. Create, calculate, and save a few loans
     
    Watts A Loan
    Watts A Loan
  13. Close the form and return to your programming environment

De-Serialization With SOAP

De-serialization in soap is performed exactly as done for the binary de-serialization. To support it, the SoapFormatter class is equipped with the Deserialize() method. This method uses the same syntax as its equivalent of the BinaryFormatter class. The approach to use it is also the same.

Practical Learning: Deserializing With SOAP

  1. In the Class Name combo box, select btnOpen
  2. In the Method Name combo box, select Click
  3. To deserialize, implement the event as follows:
     
    Private Sub btnOpen_Click(ByVal sender As Object, _
                                  ByVal e As System.EventArgs) _
                                  Handles btnOpen.Click
            If txtOpen.Text.Length = 0 Then
                MsgBox("Please enter a customer's initials or " & _
                                "a name given to a previous loan preparation")
                txtOpen.Focus()
                Exit Sub
            End If
    
            Try
                Dim LoanInfo As LoanInformation = New LoanInformation
                Dim LoanStream As FileStream = New FileStream(txtOpen.Text, _
                                         FileMode.Open, _
                                         FileAccess.ReadWrite)
                Dim LoanFormatter As SoapFormatter = New SoapFormatter
    
                Try
                    ' Open the file and store its values 
                    ' in the LoanInformation variable
                    LoanInfo = CType(LoanFormatter.Deserialize(LoanStream), _
    				 LoanInformation)
    
                    ' Retrive each value and put it in its corresponding control
                    txtEmployeeName.Text = LoanInfo.EmployeeName
                    txtCustomerFirstName.Text = LoanInfo.CustomerFirstName
                    txtCustomerLastName.Text = LoanInfo.CustomerLastName
                    txtPrincipal.Text = LoanInfo.Principal.ToString("F")
                    txtInterestRate.Text = LoanInfo.InterestRate.ToString("F")
                    txtPeriods.Text = LoanInfo.Periods.ToString()
                    cbxPeriods.SelectedIndex = LoanInfo.PeriodType
    
                    ' Since we didn't save the calculated values,
                    ' call the Click event of the Calculate button
                    btnCalculate_Click(sender, e)
                Finally
                    LoanStream.Close()
                End Try
            Catch ex As FileNotFoundException
                MsgBox("There is no file with that name")
            End Try
    End Sub
  4. In the Class Name combo box, select btnOpen
  5. In the Method Name combo box, select Click and implement the event as follows:
     
    Private Sub btnClose_Click(ByVal sender As Object, _
                                   ByVal e As System.EventArgs) _
                                   Handles btnClose.Click
            End
    End Sub
  6. Press Ctrl + F5 to execute the application
  7. Enter the initials of a previously created loan and click Open
  8. Close the form and return to your programming environment

Details on Serialization

 

Partial Serialization

In the examples we have used so far, we were saving the whole object. You can make it possible to save only some parts of the class. When creating a class, you can specify what fields would be serialized and which ones would not be. To specify that a member cannot be saved, you can mark it with the <NonSerialized()> attribute. Here is an example:

<Serializable()> Public Class Car1
    Public Make As String
    Public Model As String

    ' Because the value of a car can change,
    ' there is no reason to save it
    <NonSerialized()> _
    Public Value As Double
    Public Year As Integer
    Public Color As Integer
End Class

After creating the class, you can declare a variable of it and serialize it, using either the binary or the SOAP approach. You can then retrieve the object and its values, using any of the techniques we learned earlier.

Implementing a Custom Serialized Class

To support serialization, the .NET Framework provides the ISerializable interface. You can create a class that implements this interface to customize the serialization process. Even if you plan to use this interface, the class you create must be marked with the <Serializable> attribute.

.NET Built-In Serialized Classes

The .NET Framework is filled with many classes ready for serialization. To know that a class is ready for serialization, when viewing its documentation either in the MSDN web site or in the help documentation, check that it is marked with the [SerializableAttribute]. Here is an example of such as class:

 

The Serializable attribute of a built-in class

Some of these classes provide the properties and methods to create an object and directly save it. For some other classes, you must first create a class, mark it with the <SerializableAttribute> attribute, build an object of it, and then pass it to the .NET class.


Home Copyright © 2008-2012 FunctionX