|
Serialization: SOAP |
|
|
The .NET Framework supports another 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
|
|
- Start a new Windows Application named WattsALoan3
- In the Solution Explorer, right-click Form1.cs and click Rename
- Type LoanPreparation.cs and press Enter
- Design the form as followed:
|
Control |
Name |
Text |
Additional Properties |
GroupBox |
|
|
Loan Identification |
|
Label |
|
|
Prepared &By: |
|
TextBox |
|
txtEmployeeName |
|
|
Label |
|
|
Customer First Name: |
|
TextBox |
|
txtCustomerFirstName |
|
|
Label |
|
|
Last Name: |
|
TextBox |
|
txtCustomerLastName |
|
|
GroupBox |
|
|
Loan Preparation |
|
Label |
|
|
Principal: |
|
TextBox |
|
txtPrincipal |
0.00 |
TextAlign: Right |
Label |
|
|
Interest Rate: |
|
TextBox |
|
txtInterestRate |
8.25 |
TextAlign: Right |
Label |
|
|
% |
|
Label |
|
|
Periods: |
|
TextBox |
|
txtPeriods |
1 |
TextAlign: Text |
ComboBox |
|
cbxPeriods |
Months |
Items: Years Months Days |
GroupBox |
|
|
Results |
|
Button |
|
btnCalculate |
Calculate |
|
Label |
|
|
Interest Earned: |
|
TextBox |
|
txtInterestEarned |
0.00 |
TextAlign: Right ReadOnly: True |
Label |
|
|
Amount Earned: |
|
TextBox |
|
txtFutureValue |
0.00 |
TextAlign: Right ReadOnly: True |
GroupBox |
|
|
File Processing |
|
Label |
|
|
Loan ID: |
|
TextBox |
|
txtSave |
|
|
Button |
|
&Save |
btnSave |
|
Label |
|
|
Loan ID: |
|
TextBox |
|
txtOpen |
|
|
Button |
|
&Open |
btnOpen |
|
Button |
|
btnClose |
Close |
|
|
- On the form, click the Last Name text box
- In the Properties window, click the Events button and double-click
Leave
- Implement the event as follows:
private void txtCustomerLastName_Leave(object sender, EventArgs e)
{
var Initials = "00";
var FirstName = txtCustomerFirstName.Text;
var LastName = txtCustomerLastName.Text;
if (LastName.Length == 0)
{
MessageBox.Show("You must enter a last name");
txtCustomerLastName.Focus();
return;
}
if (FirstName.Length == 0)
Initials = LastName.Substring(0, 1) + "1";
else
Initials = FirstName.Substring(0, 1) + LastName.Substring(0, 1);
txtSave.Text = Initials;
}
- Return to the form
- On the form, double-click the Calculate button and implement its
Click event as follows:
private void btnCalculate_Click_1(object sender, EventArgs e)
{
var Principal = 0.00;
var InterestRate = 0.00;
var InterestEarned = 0.00;
var FutureValue = 0.00;
var Periods = 0.00;
// Retrieve the value of the principal
try
{
Principal = double.Parse(txtPrincipal.Text);
}
catch (FormatException)
{
MessageBox.Show("The value you entered for the principal " +
"is not valid.\nPlease try again");
}
// Retrieve the interest rate
try
{
InterestRate = double.Parse(txtInterestRate.Text) / 100;
}
catch (FormatException)
{
MessageBox.Show("The value you entered for the interest " +
"rate is not valid\nPlease try again");
}
// Get the number of periods
try
{
if (cbxPeriods.SelectedIndex == 0) // Years
Periods = double.Parse(txtPeriods.Text);
else if (cbxPeriods.SelectedIndex == 1) // Months
Periods = double.Parse(txtPeriods.Text) / 12;
else // if (cbxPeriods.SelectedIndex == 2) Days
Periods = double.Parse(txtPeriods.Text) / 360;
}
catch (FormatException)
{
MessageBox.Show("The value you entered for the number " +
"of periods is not valid\nPlease try again");
}
var InterestRatePeriods = InterestRate * Periods;
var InterestPlus1 = InterestRatePeriods + 1;
FutureValue = Principal * InterestPlus1;
InterestEarned = FutureValue - Principal;
txtInterestEarned.Text = InterestEarned.ToString("F");
txtFutureValue.Text = FutureValue.ToString("F");
}
- Execute the application to make sure it is fine
- After using it, close the form and return to your programming
environment
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 string Make;
public string Model;
public uint Year;
public byte Color;
}
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 variable 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
|
|
- To create a new class, on the main menu, click Project -> Add
Class...
- Set the Name to LoanInformation and click Add
- Change the file as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WattsALoan3
{
[Serializable]
public class LoanInformation
{
public string EmployeeName;
public string CustomerFirstName;
public string CustomerLastName;
public double Principal;
public double InterestRate;
public double Periods;
public int PeriodType;
}
}
- To add SOAP support to your project, on the main menu, click Project
-> Add Reference...
- In the Add Reference dialog box and in the .NET tab, scroll down and
select System.Runtime.Serialization.Formatters.Soap:
- Click OK
- On the form, double-click the Save button
- In the top section of the form, type the following:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.Serialization.Formatters.Soap;
- Scroll down and implement the event as follows:
private void btnSave_Click(object sender, EventArgs e)
{
if (txtSave.Text.Length == 0)
{
MessageBox.Show("Please enter the customer " +
"initials or a name for the loan");
txtSave.Focus();
return;
}
var infLoan = new LoanInformation();
infLoan.EmployeeName = txtEmployeeName.Text;
infLoan.CustomerFirstName = txtCustomerFirstName.Text;
infLoan.CustomerLastName = txtCustomerLastName.Text;
infLoan.Principal = double.Parse(txtPrincipal.Text);
infLoan.InterestRate = double.Parse(txtInterestRate.Text);
infLoan.Periods = double.Parse(txtPeriods.Text);
infLoan.PeriodType = cbxPeriods.SelectedIndex;
var stmLoan = new FileStream(txtSave.Text, FileMode.Create,
FileAccess.Write);
var sfmLoan = 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();
}
}
- Press Ctrl + F5 to execute the application
- Create, calculate, and save a few loans
- 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
|
|
- To deserialize, on the form, double-click the Open button and
implement its event as follows:
private void btnOpen_Click(object sender, EventArgs e)
{
if (txtOpen.Text.Length == 0)
{
MessageBox.Show("Please enter a customer's initials or " +
"a name given to a previous loan preparation");
txtOpen.Focus();
return;
}
try
{
var infLoan = new LoanInformation();
var stmLoan = new FileStream(txtOpen.Text,
FileMode.Open,
FileAccess.ReadWrite);
var sfmLoan = new SoapFormatter();
try
{
// Open the file and store its values
// in the LoanInformation variable
infLoan = (LoanInformation)sfmLoan.Deserialize(stmLoan);
// Retrive each value and put it in its corresponding control
txtEmployeeName.Text = infLoan.EmployeeName;
txtCustomerFirstName.Text = infLoan.CustomerFirstName;
txtCustomerLastName.Text = infLoan.CustomerLastName;
txtPrincipal.Text = infLoan.Principal.ToString("F");
txtInterestRate.Text = infLoan.InterestRate.ToString("F");
txtPeriods.Text = infLoan.Periods.ToString();
cbxPeriods.SelectedIndex = infLoan.PeriodType;
// Since we didn't save the calculated values,
// call the Click event of the Calculate button
btnCalculate_Click(sender, e);
}
finally
{
stmLoan.Close();
}
}
catch (FileNotFoundException)
{
MessageBox.Show("There is no file with that name");
}
}
- Return to the form and double-click the Close button
- Implement its Click event as follows:
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
- Press Ctrl + F5 to execute the application
- Enter the initials of a previously created loan and click Open
- Close the form and return to your programming environment
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 Car
{
public string Make;
public string Model;
// Because the value of a car can change,
// there is no reason to save it
[NonSerialized]
public decimal Value;
public uint Year;
public byte Color;
}
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:
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 [Serializable] attribute,
build an object of it, and then pass it to the .NET class.
|
|