Tải bản đầy đủ (.pdf) (32 trang)

Tài liệu Module 12: Serialization docx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (770.46 KB, 32 trang )









Contents
Overview 1
Serialization Scenarios 2
Serialization Attributes 4
Object Graph 5
Serialization Process 7
Serialization Example 9
Deserialization Example 10
Custom Serialization 12
Custom Serialization Example 14
Security Issues 17
Lab 12: Serialization 18
Review 27

Module 12: Serialization


Information in this document, including URL and other Internet Web site references, is subject to
change without notice. Unless otherwise noted, the example companies, organizations, products,
domain names, e-mail addresses, logos, people, places and events depicted herein are fictitious,
and no association with any real company, organization, product, domain name, e-mail address,
logo, person, place or event is intended or should be inferred. Complying with all applicable
copyright laws is the responsibility of the user. Without limiting the rights under copyright, no


part of this document may be reproduced, stored in or introduced into a retrieval system, or
transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or
otherwise), or for any purpose, without the express written permission of Microsoft Corporation.

Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual
property rights covering subject matter in this document. Except as expressly provided in any
written license agreement from Microsoft, the furnishing of this document does not give you any
license to these patents, trademarks, copyrights, or other intellectual property.

 2001-2002 Microsoft Corporation. All rights reserved.

Microsoft, ActiveX, BizTalk, IntelliMirror, Jscript, MSDN, MS-DOS, MSN, PowerPoint,
Visual Basic, Visual C++, Visual C#, Visual Studio, Win32, Windows, Windows Media, and
Window NT are either registered trademarks or trademarks of Microsoft Corporation in the U.S.A.
and/or other countries.

The names of actual companies and products mentioned herein may be the trademarks of their
respective owners.



Module 12: Serialization iii


Instructor Notes
After completing this module, students will be able to:
• Write an application that serializes and deserializes an object graph by using
either a binary or Simple Object Access Protocol (SOAP) XML format.

Materials and Preparation

This section provides the materials and preparation tasks that you need to teach
this module.
Required Materials
To teach this module, you need the Microsoft
®
PowerPoint
®
file 2349B_12.ppt.
Preparation Tasks
To prepare for this module, you should:
!
Read all of the materials for this module.
!
Complete the lab.

Presentation:
30 Minutes

Lab:
45 Minutes
iv Module 12: Serialization


Module Strategy
Use the following strategy to present this module:
!
Serialization Scenarios
Discuss briefly how serialization is used in scenarios such as persisting in-
memory objects to disk and in remoting. Mention the Microsoft .NET
Framework’s support for serialization and deserialization as an introduction

to the rest of the module.
!
Serialization Attributes
Explain how to mark a class with serialization attributes in C# by using the
Serializable attribute. Also cover the NonSerialized attribute.
!
Object Graph
Use the diagram on the Object Graph slide to discuss the object graph
concept and the algorithm that is used to serialize or deserialize an object
graph.
!
Serialization Process
Introduce the classes that are used in the serialization process.
!
Serialization Example
Discuss the code example on the Serialization Example slide in which
default serialization is performed on a graph of objects, whose root is an
ArrayList, and the serialized stream is written to a FileStream in binary
format.
!
Deserialization Example
Use the preceding serialization example to show how to create a clone of the
graph by deserializing it.
!
Custom Serialization
Discuss when to use custom serialization and the implementation details of
using the ISerializable interface to perform custom serialization and
deserialization.
!
Custom Serialization Example

Show how to provide custom serialization for a class named
ISerializableExample.
!
Security Issues
Because the serialization engine handles both the public and private state of
the objects that are passed to it, emphasize that streams with private data
should be treated carefully, and that some form of encryption should be used
for sensitive data, before that data is transmitted over the wire or persisted to
disk.

Module 12: Serialization 1


Overview
!
Serialization Scenarios
!
Serialization Attributes
!
Object Graph
!
Serialization Process
!
Serialization Example
!
Deserialization Example
!
Custom Serialization
!
Custom Serialization Example

!
Security Issues

*****************************
ILLEGAL FOR NON
-
TRAINER USE
******************************
Serialization is the process of converting a graph of objects into a linear
sequence of bytes. That sequence of bytes can be sent elsewhere, for example,
to a remote computer, and be deserialized, thereby making a clone in the remote
memory of the original graph of objects.
After completing this module, you will be able to:
• Write an application that serializes and deserializes an object graph by using
either a binary or Simple Object Access Protocol (SOAP) XML format.

Topic Objective
To provide an overview of
the module topics and
objectives.
Lead-in
In this module, you will learn
about serialization and learn
how to write an application
that serializes and
deserializes an object graph
by using a binary or SOAP
XML format.
2 Module 12: Serialization



Serialization Scenarios
!
Persistence
"
Store and retrieve a graph of objects to and from a file
!
Remoting
"
Pass by value arguments that are transmitted between
processes

*****************************
ILLEGAL FOR NON
-
TRAINER USE
******************************
Serialization is used in some very common scenarios, such as persisting a graph
of objects to disk or to objects in another process. The Microsoft
®
.NET
Framework provides support for serialization and deserialization.
Persistence
Consider a simple single-user desktop application, such as a two-dimensional
drafting package that is built by using object-oriented techniques. In such an
application, a drawing is composed of different kinds of graphical objects of
various types. The application represents the drawing as a graph of in-memory
objects. One object represents the root of the entire picture. For example, a
simple round table could be represented by a graph that consists of a root object
that is an instance of a circle class. This instance of the circle class has four

children that are each instances of a line class.
To save the entire drawing to a disk file so the drawing can be restored after
rebooting the computer, you could force each class to implement a serialize and
corresponding deserialize method. However, this approach is a potentially
burdensome task for the application programmer.
Serialization in the .NET Framework
The .NET Framework common language runtime reduces the amount of work
that is involved in serialization. At run time, the common language runtime
maintains metadata that allows serialization code to discover the types and
values of all fields and properties that make up any object. Using the common
language runtime, an application requires only a few lines of code to serialize a
object, such as the drawing described in the preceding paragraphs, and write it
to a file, or to deserialize such a file into an in-memory graph of objects.
Topic Objective
To show how serialization is
used.
Lead-in
Serialization is used in some
very common scenarios,
such as persisting a graph
of objects to disk or to
objects in another process.
Module 12: Serialization 3


Remoting
In distributed computing, objects in one process may need to communicate with
objects in another process. In the .NET Framework, the term remoting is
typically used to refer to the process in which an object invokes a method in
another object that is not in the same application domain. If the remote method

takes as one of its arguments an object that lies at the root of a graph of objects,
and if all of the objects in the graph are marked as remote-by-value, you must
serialize a copy of the object graph and pass the graph to the remote object. The
remote object must then deserialize the argument into an in-memory graph of
objects.
For more information about remoting, see Module 13, “Remoting and Web
Services,” in Course 2349B, Programming with the Microsoft .NET Framework
(Microsoft Visual C# .NET).
4 Module 12: Serialization


Serialization Attributes
!
To Mark a Class, Use Serializable Attribute
!
To Skip Specified Members, Use NonSerialized Attribute
!
To Provide Custom Serialization, Implement
ISerializable
[Serializable] public class MyClass {}
[Serializable] public class MyClass {}
[Serializable] public class MyClass {
[NonSerialized] int _cashSize;
//
}
[Serializable] public class MyClass {
[NonSerialized] int _cashSize;
//
}


*****************************
ILLEGAL FOR NON
-
TRAINER USE
******************************
If you are writing a class, you should be aware of serialization. The common
language runtime’s serialization services are built with the assumption that a
type is not serializable unless the type is specifically marked as serializable. In
the simplest case, all you need to do is mark a class as serializable because the
runtime metadata understands everything about each object’s layout in memory,
and its field and property definitions.
To mark a type as serializable in C#, you use the Serializable attribute, which
is a reserved custom attribute. All fields in classes with this attribute are
serialized, even private fields.
In the following example, MyClass is marked as serializable:
[Serializable] public class MyClass {}

For slightly more complex classes that have state that is invalid to serialize, the
runtime provides support for marking those fields and properties as transient.
For example, the following code uses the NonSerialized attribute to ensure that
the _cashSize member of MyClass is not serialized:
[Serializable] public class MyClass
{
[NonSerialized] int _cashSize;
//
}

The small set of classes that need to participate in their own serialization and
deserialization can provide a custom implementation of the ISerializable
interface. For more information about custom serialization, see Custom

Serialization in this module.
Topic Objective
To explain how to mark a
class with serialization
attributes in C#.
Lead-in
If you are writing a class,
you should be aware of
serialization.
Module 12: Serialization 5


Object Graph
Dog
Cat Duck Mouse
Horse
Duck
3
3
7
7
4
4
2
2
9
9
1
1


*****************************
ILLEGAL FOR NON
-
TRAINER USE
******************************
An object graph is a set of objects with references to each other. Serialization
must provide a way to represent the links between the graph’s objects in the
serialized stream that is created in the serialization process.
Understanding Object Graphs
Serialization of an object graph must provide a way to represent the links
between the graph’s objects in the serialized stream that it creates. The value
that is held in the field of the in-memory object, which links to another object,
is essentially a 32-bit address. This address has meaning only in the owner
address space and may change during garbage collection. Therefore,
serialization must allocate a unique number to each object in the stream.
The illustration in the slide shows a graph of animal objects. Each object is
represented as a box with its identification number inside the box and its class
name to the right of the box.
You can represent the graph of objects that is shown in this illustration with a
serialized stream, as in the following example:
Dog, 3, ref4, ref7, ref1 || Cat, 4, ref9 || Duck, 7 || Mouse,
1, ref9, ref2 || Horse, 9, ref4 || Duck, 2

The order in which you stream out the objects does not matter, nor does it
matter what numbers you assign to the objects. What does matter is that no two
objects are assigned the same number. The object numbers are significant only
within a serialized stream. They are simply a way to represent the graph
topology and to allow you to reconstruct a copy of that graph, perhaps on
another computer.
Topic Objective

To define an object graph
and explain its function.
Lead-in
An object graph is a set of
objects that share a set of
references to each other.
6 Module 12: Serialization


Tracking Object References
An algorithm that visits objects one at a time clearly must keep track of which
objects it has already visited, for example, by using an internal list. Without due
care, the algorithm may incorrectly serialize or deserialize an object graph.
For example, in the object graph in the illustration, to avoid entering an infinite
loop, you must detect the cycle in the graph that occurs because of the mutual
references between Cat 4 and Horse 9. During serialization, you must note that
the Cat 4 that is linked to by Dog 3 is the same Cat 4 that is linked to by Horse
9 to ensure that deserialization will result in both Dog 3 and Horse 9 referring
to the same Cat 4 object and not to two different copies.
Module 12: Serialization 7


Serialization Process
!
Classes Used by the Default Serialization Process
"
ObjectIDGenerator – generates IDs for objects
"
ObjectManager – tracks objects as they are being
deserialized

!
Examples of Classes Used with Serialized Streams
"
FileStream, MemoryStream, NetworkStream
!
Formatter Class
"
Writes or reads data in a specified format to the output
or input streams
"
Runtime provides BinaryFormatter and SoapFormatter

*****************************
ILLEGAL FOR NON
-
TRAINER USE
******************************
The process of serializing an object graph involves identifying the individual
objects in the graph and the relationships between them.
Classes Used by the Default Serialization Process
To create and track object ID numbers, serialization uses several classes, as
follows:
!
ObjectIDGenerator
The ObjectIDGenerator class generates IDs for objects. It keeps track of
objects that have already been seen, so when you ask for the ID of an object,
the ObjectIDGenerator knows whether to return the existing ID, or to
generate, and remember, a new ID.
!
ObjectManager

The ObjectManager class keeps track of objects as they are being
deserialized. During deserialization, queries are made to the
ObjectManager to determine whether a reference to an object that is in the
serialized stream refers to an object that has already been deserialized or to
an object that has not yet been deserialized. A reference to an object that has
already been deserialized is called a backward reference. A reference to an
object that has not yet been serialized is called a forward reference.

Topic Objective
To introduce the classes
that are used in the
serialization process.
Lead-in
The process of serializing
an object graph involves
identifying the individual
objects in the graph and the
relationships between them.
8 Module 12: Serialization


Both the ObjectIDGenerator and ObjectManager classes are pluggable, so
you can build your own alternatives.

During deserialization, fields are returned in the order in which they are
returned from reflection. Reflection does not guarantee that it will follow
metadata ordering.

You can serialize to many different kinds of streams, for example, to a
FileStream, a MemoryStream, or a NetStream. The serialized stream’s

format is determined by the formatter object that you instantiate.
The .NET Framework runtime provides the following formatter classes:
!
BinaryFormatter
The BinaryFormatter class is used for a compact binary representation.
!
SoapFormatter
The SoapFormatter class is used for an XML representation.

Because formatters are pluggable, you can also build your own formatters.
Note
Module 12: Serialization 9


Serialization Example
class SerializeExample{
public static void Main(String[] args) {
// create the object graph
ArrayList l = new ArrayList();
for (int x=0; x< 100; x++) {
l.Add (x);
}
// create the filestream
FileStream s = File.Create("foo.bin");
// create the BinaryFormatter
BinaryFormatter b = new BinaryFormatter();
// serialize the graph to the stream
b.Serialize(s, l);
s.Close();
}

}
class SerializeExample{
public static void Main(String[] args) {
// create the object graph
ArrayList l = new ArrayList();
for (int x=0; x< 100; x++) {
l.Add (x);
}
// create the filestream
FileStream s = File.Create("foo.bin");
// create the BinaryFormatter
BinaryFormatter b = new BinaryFormatter();
// serialize the graph to the stream
b.Serialize(s, l);
s.Close();
}
}

*****************************
ILLEGAL FOR NON
-
TRAINER USE
******************************
The following code sample shows how to perform default serialization of a
graph of objects, whose root is an ArrayList. The serialized stream is written to
a FileStream in binary format.
using System;
using System.IO;
using System.Collections;
using System.Runtime.Serialization;

using System.Runtime.Serialization.Formatters.Binary;

class SerializeExample
{

public static void Main(String[] args)
{
// create the object graph
ArrayList l = new ArrayList();
for (int x=0; x< 100; x++)
{
l.Add (x);
}
// create the filestream
FileStream s = File.Create("foo.bin");
// create the BinaryFormatter
BinaryFormatter b = new BinaryFormatter();
// serialize the graph to the stream
b.Serialize(s, l);
s.Close();
}
}

Topic Objective
To provide an example of
serialization of an object
graph.
Lead-in
This code sample shows
how to perform default

serialization of a graph of
objects, whose root is an
ArrayList.
10 Module 12: Serialization


Deserialization Example
class DeSerialize
{
public static void Main(String[] args)
{
// open the filestream
FileStream s = File.OpenRead("foo.bin");
// create the formatter
BinaryFormatter b = new BinaryFormatter();
// deserialize
ArrayList p = (ArrayList) b.Deserialize(s);
s.Close();
// print out the new object graph
// see module text for PrintValues’ code
PrintValues(p);
}
class DeSerialize
{
public static void Main(String[] args)
{
// open the filestream
FileStream s = File.OpenRead("foo.bin");
// create the formatter
BinaryFormatter b = new BinaryFormatter();

// deserialize
ArrayList p = (ArrayList) b.Deserialize(s);
s.Close();
// print out the new object graph
// see module text for PrintValues’ code
PrintValues(p);
}

*****************************
ILLEGAL FOR NON
-
TRAINER USE
******************************
The preceding Serialization Example shows how to perform default
serialization of a graph of objects, whose root is an ArrayList, with a serialized
stream that is written to a FileStream in binary format.
The following code sample shows how to create a clone of the graph by
deserializing it. The root of the clone graph is called p.
using System;
using System.IO;
using System.Collections;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

class DeSerialize
{

public static void Main(String[] args)
{
// open the filestream

FileStream s = File.OpenRead("foo.bin");

// create the formatter
BinaryFormatter b = new BinaryFormatter();
// deserialize
ArrayList p = (ArrayList) b.Deserialize(s);
s.Close();
// print out the new object graph
PrintValues(p);
}

(Code continued the following page.)
Topic Objective
To show how to create a
clone of the graph by
deserializing it.
Lead-in
The preceding Serialization
Example shows how to
perform default serialization
of a graph of objects, whose
root is an ArrayList, with a
serialized stream that is
written to a FileStream in
binary format.
Module 12: Serialization 11


public static void PrintValues( IEnumerable myList )
{

System.Collections.IEnumerator myEnumerator =
myList.GetEnumerator();
while ( myEnumerator.MoveNext() )
Console.WriteLine( "{0}", myEnumerator.Current );
}

}

12 Module 12: Serialization


Custom Serialization
!
Customize Serialization by Implementing ISerializable:
"
When some of the data is not valid after deserialization
"
When some of the data must be obtained by calculation
!
ISerializable Requires:
"
GetObjectData method, called during serialization,
which returns a PropertyBag of type SerializationInfo
"
PropertyBag, which contains the type of the object
being serialized and the name/object pairs for the values
being serialized
"
A constructor, called during deserialization, which uses
SerializationInfo to reconstitute the state of the object


*****************************
ILLEGAL FOR NON
-
TRAINER USE
******************************
This module has so far discussed the default serialization process. However,
you may also want to customize the way that data from a given object is
serialized.
Custom serialization can be useful when some of the data that is associated with
an object is no longer valid after deserialization. You may want to use custom
serialization when working with pointers or hashcodes, or when you want to
create data through calculations or other means that allow you to reconstruct the
full state of the object during deserialization.
To perform custom serialization, you should implement the ISerializable
interface on the given object.
Implementation Details Required by ISerializable
To implement the ISerializable interface, you implement the GetObjectData
method on your object and add a constructor that takes a SerializationInfo and
a StreamingContext, as shown in Custom Serialization Example in this
module.
When GetObjectData is called during serialization, you are responsible for
populating a SerializationInfo object. A SerializationInfo object is a
PropertyBag that contains the type of the object that is being serialized and the
name/object pairs for the values that are being serialized.
The Formatter emits the data out onto the wire in the method required by its
particular format. You are free to serialize as few or as many fields as you want,
but the data that is transmitted must be sufficient to reconstitute the entire state
of the object. If the base object of the current class implements ISerializable, it
is usually correct to call the base object’s ISerializable.GetObjectData and

add any additional fields that are required for serializing the derived class to the
returned SerializationInfo.
Topic Objective
To explain what is required
to implement ISerializable
for performing custom
serialization.
Lead-in
This module has so far
discussed the default
serialization process.
However, you may also
want to customize the way
data from a given object is
serialized.
Module 12: Serialization 13


Deserialization
Deserialization occurs during the call to the class’s constructor. If you need to
create custom deserialization of an object, you use the object’s
SerializationInfo, which has been populated with the type of the object and the
name/object pairs that were transmitted over the stream. You are responsible for
completely reconstituting the state of the object from this information. If the
base class also implements ISerializable, you are responsible for calling the
base class’s constructor. The serialization infrastructure will delay the call on
this constructor until the entire SerializationInfo has been completed.
If, for example, the SerializationInfo that is transmitted references objects A,
B, and C, the SerializationInfo that is passed to the constructor will have been
populated with references to objects A, B, and C. However, there is no

guarantee that any of the objects that are referenced by A, B, or C has been
completed.
Because there is no guarantee that any of the objects that are referenced by A,
B, or C have been completed, you cannot safely call any code on A, B, or C that
may require the objects to which they refer. For some objects, this code may
include code as simple as GetHashCode.
If your code requires you to perform any execution that is based on the value of
data that is contained in the objects that are referenced, it is usually best to
cache the SerializationInfo and then implement IDeserializationCallback.
14 Module 12: Serialization


Custom Serialization Example
[Serializable] public class ExampleFoo : ISerializable
{
public int i, j, k;
public ExampleFoo() {}
internal ExampleFoo(SerializationInfo si,
StreamingContext context) {
//Restore our scalar values.
i = si.GetInt32("i");
j = si.GetInt32("j");
k = si.GetInt32("k");
}
public void GetObjectData(SerializationInfo si,
StreamingContext context) {
//SerializationInfo - essentially a property bag
//Add our three scalar values;
si.AddValue("i", i);
si.AddValue("j", j);

si.AddValue("k", k);
Type t = this.GetType();
si.AddValue("TypeObj", t);
}
}
[Serializable] public class ExampleFoo : ISerializable
{
public int i, j, k;
public ExampleFoo() {}
internal ExampleFoo(SerializationInfo si,
StreamingContext context) {
//Restore our scalar values.
i = si.GetInt32("i");
j = si.GetInt32("j");
k = si.GetInt32("k");
}
public void GetObjectData(SerializationInfo si,
StreamingContext context) {
//SerializationInfo - essentially a property bag
//Add our three scalar values;
si.AddValue("i", i);
si.AddValue("j", j);
si.AddValue("k", k);
Type t = this.GetType();
si.AddValue("TypeObj", t);
}
}

*****************************
ILLEGAL FOR NON

-
TRAINER USE
******************************
The following example shows how to provide custom serialization for a class:
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Soap;

public class Sample
{
public static void Main()
{
ToFile();
FromFile();
}

(Code continued the following page.)
Topic Objective
To provide an example of
custom serialization.
Lead-in
This example shows how to
provide custom serialization
for a class named
ISerializableExample.
Module 12: Serialization 15



public static void ToFile()
{
Console.WriteLine("ToFile");
ExampleFoo fooOut = new ExampleFoo();
fooOut.i = 1;
fooOut.j = 20;
fooOut.k = 50;

Console.WriteLine("i: {0}", fooOut.i);
Console.WriteLine("j: {0}", fooOut.j);
Console.WriteLine("k: {0}", fooOut.k);

IFormatter objFormatterToStream = new SoapFormatter();
Stream toStream = new FileStream("myFoo.xml",
FileMode.Create, FileAccess.Write, FileShare.None);
objFormatterToStream.Serialize(toStream, fooOut);
toStream.Close();
}

public static void FromFile()
{
Console.WriteLine("FromFile");
//Then you can read it back in with code like this:
IFormatter objFormatterFromStream = new SoapFormatter();
Stream fromStream = new FileStream("myFoo.xml",
FileMode.Open, FileAccess.Read, FileShare.Read);
ExampleFoo fooIn = (ExampleFoo)
objFormatterFromStream.Deserialize(fromStream);
fromStream.Close();


Console.WriteLine("i: {0}", fooIn.i);
Console.WriteLine("j: {0}", fooIn.j);
Console.WriteLine("k: {0}", fooIn.k);
}
}


[Serializable]
public class ExampleFoo : ISerializable
{
public int i, j, k;

public ExampleFoo()
{
}

internal ExampleFoo(SerializationInfo si,
StreamingContext context)
{
//Restore our scalar values.
i = si.GetInt32("i");
j = si.GetInt32("j");
k = si.GetInt32("k");
}

(Code continued on the following page.)
16 Module 12: Serialization


public void GetObjectData(SerializationInfo si,

StreamingContext context)
{
//SerializationInfo is essentially a property bag.

//Add our three scalar values;
si.AddValue("i", i);
si.AddValue("j", j);
si.AddValue("k", k);

Type t = this.GetType();
si.AddValue("TypeObj", t);
}
}

Outputs:
ToFile
i: 1
j: 20
k: 50
FromFile
i: 1
j: 20
k: 50

Module 12: Serialization 17


Security Issues
!
Serialization Handles an Object’s Private Data

"
If private data is sensitive, consider encrypting the
stream before transmitting or saving to a disk
"
System.Security.Cryptography namespace contains
classes to perform cryptography
The CryptoStream class can be used to encrypt
streams of serialized data

*****************************
ILLEGAL FOR NON
-
TRAINER USE
******************************
The serialization engine handles both the public and private state of the objects
that are passed to it. When serializing an object to a stream, you must remember
that the stream now contains the public and private data of the object.
If the private data is sensitive, you should treat the stream with particular care.
For example, the stream should not be transmitted over the wire or persisted to
disk without some form of encryption.
Topic Objective
To alert students to the
need for security when
serializing objects.
Lead-in
The serialization engine
handles both the public and
private state of the objects
that are passed to it.
18 Module 12: Serialization



Lab 12: Serialization

*****************************
ILLEGAL FOR NON
-
TRAINER USE
******************************
Objectives
After completing this lab, you will be able to:
• Create an application that uses serialization as it is implemented by the
.NET Framework, to persist an object graph to and from a disk file in both
binary and SOAP XML format.

Lab Setup
Starter and solution files are associated with this lab. The starter files are in the
folder <install folder>\Labs\Lab12\Starter, and the solution files are in the
folder <install folder>\Labs\Lab12\Solution.
Scenario
In this lab, you will create a Microsoft

Visual Studio
®
.NET console application
that uses the common language runtime’s ability to serialize an object graph in
memory to disk. You will create binary and SOAP formatter implementations
of the application.
In the first exercise, you will create a singly-linked linked list, which you will
fill with values and serialize to a file on disk. You will then deserialize the list

from the file on disk, thus restoring the list to an object graph in memory.
During deserialization, the elements within the list are swapped multiple times.
In the second exercise, you will modify the application to demonstrate the
ability of the .NET Framework’s serialization mechanism to handle object
graphs that contain multiple references to the same object and that contain
objects that have mutual references, which can create cycles in the graph.
Estimated time to complete this lab: 45 minutes
Topic Objective
To introduce the lab.
Lead-in
In this lab, you will write a
client/server application that
uses serialization.
Module 12: Serialization 19


Exercise 1
Creating the Basic Serialization Application
In this exercise, you will modify the Serialization application to provide
methods to serialize and deserialize a linked list.
!
To create the basic Serialization application in binary format
1. In the <install folder>\Labs\Lab12\Starter directory, open the Serialization
project in Visual Studio .NET and examine the Serialize.cs and
LinkedList.cs source files.
2. In Serialize.cs, locate the SaveListToDisk method, and add code to:
a. Create a Stream object that is initialized to a file named Linkedlist.bin
by using the static File.Create method.
b. Create a new BinaryFormatter object.
c. Invoke the method of the BinaryFormatter that serializes the

LinkedList parameter to the stream.
d. Close the file.
3. In Serialize.cs, locate the LoadListFromDisk method and add code to:
a. Create a Stream object that is initialized to a file named Linkedlist.bin
by using the static File.OpenRead method.
b. Create a new BinaryFormatter object.
c. Invoke the method of the BinaryFormatter that deserializes the stream
into a LinkedList named list2.
d. Close the file.
e. Output the contents of list2 to console by calling the LinkedList method
Draw().
f. Return list2.
4. Build the Serialization application.
20 Module 12: Serialization


5. Step through the application in the Visual Studio .NET debugger, and note
that due to the random swapping your output may vary slightly from the
following:
Entering Scope 1
Creating and filling List
List: 1 2 3 4 5 6 7 8 9
Serializing LinkedList to file
Leaving Scope 1

Entering Scope 2
Deserializing LinkedList from binary file
List: 1 2 3 4 5 6 7 8 9
Swapping Entries
Swapping 1 and 2

Swapping 3 and 4
Swapping 5 and 6
Swapping 7 and 8
List: 2 1 4 3 6 5 8 7 9
Serializing LinkedList to file
Leaving Scope 2

Entering Scope 3
Deserializing LinkedList from binary file
List: 2 1 4 3 6 5 8 7 9
Swapping Random Entries
Swapping 2 and 8
Swapping 4 and 3
Swapping 4 and 3
Swapping 6 and 5
Swapping 1 and 4
Swapping 1 and 8
Swapping 2 and 4
Swapping 3 and 5
Swapping 7 and 2
Swapping 5 and 4
Swapping 6 and 2
Swapping 9 and 5
Swapping 1 and 7
Swapping 7 and 8
Swapping 8 and 2
List: 2 1 7 4 3 8 9 6 5
Serializing LinkedList to file
Leaving Scope 3


Entering Scope 4
Deserializing LinkedList from binary file
List: 2 1 7 4 3 8 9 6 5
Removing Entries
Removing 1
Removing 2
Removing 3
List: 7 4 8 9 6 5
Serializing LinkedList to file
Leaving Scope 4

Module 12: Serialization 21



You can open a binary file using Visual Studio .NET by running
Microsoft Windows
®
Explorer, Explorer.exe, and navigating to the binary
file’s icon. Then either right-click on the icon and choose Open With
Microsoft Visual Studio .NET, or drag and drop the icon into a running
Visual Studio .NET application’s left-hand File View pane.

6. Using Visual Studio .NET, open and visually examine the contents of the
Linkedlist.bin file in the bin\Debug subdirectory, and note the serialized list
data’s format, structure, and size.

!
To create the basic Serialization application in SOAP format
1. Add code to the SaveListToDisk and LoadListFromDisk methods to use

the SoapFormatter to write to and read the LinkedList parameter to and
from a file named Linkedlist.soap.
2. Build and execute the application, and confirm that the console output
remains correct.
3. Using Visual Studio .NET, open and visually examine the contents of the
Linkedlist.soap file in the bin\Debug subdirectory, and note the serialized
list data’s format and size. Compare this list data’s format, structure, and
size to the Linkedlist.bin list data’s format, structure, and size.

Note

×