Anda di halaman 1dari 26

Lab Answer Key for Module 6: Serializing Data

Table of Contents Lab: Serializing Data 1

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, email 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. The names of manufacturers, products, or URLs are provided for informational purposes only and Microsoft makes no representations and warranties, either expressed, implied, or statutory, regarding these manufacturers or the use of the products with any Microsoft technologies. The inclusion of a manufacturer or product does not imply endorsement of Microsoft of the manufacturer or product. Links are provided to third party sites. Such sites are not under the control of Microsoft and Microsoft is not responsible for the contents of any linked site or any link contained in a linked site, or any changes or updates to such sites. Microsoft is not responsible for webcasting or any other form of transmission received from any linked site. Microsoft is providing these links to you only as a convenience, and the inclusion of any link does not imply endorsement of Microsoft of the site or the products contained therein. 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. 2008 Microsoft Corporation. All rights reserved. Microsoft, BizTalk, IntelliSense, MSDN, Outlook, PowerPoint, SQL Server, Visual Basic, Visual C#, Visual Studio, Windows, Windows NT and Windows Server are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries. The names of actual companies and products mentioned herein may be the trademarks of their respective owners.

Version 1.2

Lab Answer Key for Module 6: Serializing Data

Lab: Serializing Data


Exercise 1 Serializing and Deserializing Data Across a Network by Using Runtime Serialization
Task 1: Review and modify the definition of the BankCustomer class to support serialization
1. Click Start, point to All Programs, point to Microsoft Visual Studio 2005, and then click Microsoft Visual Studio 2005. 2. Open the Serializer solution in the E:\Labfiles\Starter\CS\Ex1\Serializer folder (if you are using the Microsoft Visual C# development tool) or the E:\Labfiles\Starter\VB\Ex1\Serializer folder (if you are using the Microsoft Visual Basic development system). This solution contains the following four projects: Bank, which is a class library project that contains the definition of the BankCustomer class. NetworkLib, which is a class library project that contains two helper classes that are called Client and Server to provide static (C#) or Shared (Visual Basic) methods to connect and create a NetworkStream object. Receiver, which is a console application project that you will use to deserialize and display a BankCustomer object that is transmitted over the network. Sender, which is a console application project that you will use to create and serialize a BankCustomer object for transmission over the network.

3. In the Bank project, in the Bank.cs file (if you are using Visual C#) or the Bank.vb file (if you are using Visual Basic), examine the BankCustomer class. Note the following features of the class: It is in a namespace that is called Bank. It contains four private fields that hold the customer ID, name, balance, and personal identification number (PIN). It provides a constructor that populates the ID and name fields and sets the balance and PIN to default values. It does not provide a default constructor. It provides public read-only access to the customer ID and name through the CustomerID and CustomerName properties. It enables customers to change their PIN by using the SetCustomerPin method, specifying the existing PIN and the new PIN.

Lab Answer Key for Module 6: Serializing Data

It enables customers to use the Deposit method to add money to the account. This method is not PIN-protected and performs no checks as to the validity of the amount that is deposited in this prototype class. It enables customers to use the Withdraw method to remove money from the account. This method is PIN-protected but performs no further checks as to the validity of the amount that is withdrawn. It enables customers to use the GetCustomerBalance method to find out their current balance. This method is PIN-protected.

4. Tag the BankCustomer class with the SerializableAttribute attribute to enable it to be serialized by using runtime serialization. Your code should resemble the statement that appears in bold in the following examples.
[Visual C#] [Serializable()] public class BankCustomer { ... }

[Visual Basic] <Serializable()> _ Public Class BankCustomer ... End Class

5. Build the solution, and then correct any compiler errors.

Task 2: Serialize and transmit customer information in binary format


1. In Solution Explorer, right-click the Sender project, and then add references to the Bank and NetworkLib projects. 2. In the Sender project, open the Program.cs file (if you are using Visual C#) or the Program.vb file (if you are using Visual Basic). 3. At the top of the file, add statements to bring the System.Runtime.Serialization.Formatters.Binary, System.Net.Sockets, NetworkLib, and Bank namespaces into scope.
Note: If you are using Visual Basic, you must import the NetworkLib.NetworkLib and Bank.Bank namespaces.

Lab Answer Key for Module 6: Serializing Data

Your code should resemble the statements in the following examples.


[Visual C#] using System.Runtime.Serialization.Formatters.Binary; using System.Net.Sockets; using NetworkLib; using Bank;

[Visual Imports Imports Imports Imports

Basic] System.Runtime.Serialization.Formatters.Binary System.Net.Sockets NetworkLib.NetworkLib Bank.Bank

4. In the Program class, in the Main method, add code to create an instance of the BankCustomer class that is called cust. Specify a customer ID of 1 and a name of Fred. Your code should resemble the statement that appears in bold in the following examples.
[Visual C#] static void Main(string[] args) { BankCustomer cust = new BankCustomer(1, "Fred"); }

[Visual Basic] Shared Sub Main() Dim cust As New BankCustomer(1, "Fred") End Sub

5. To verify the functionality of the BankCustomer object, add statements to perform the following tasks: a. Change the PIN of this new customer from the string 1234 (the default) to the string 8765. b. Deposit 150 into the account. c. Withdraw 120 from the account. d. Display the balance of the account. Your code should resemble the statements that appear in bold in the following examples.
[Visual C#] static void Main(string[] args) {

Lab Answer Key for Module 6: Serializing Data

BankCustomer cust = new BankCustomer(1, "Fred"); cust.SetCustomerPin("1234", "8765"); cust.Deposit(150); cust.Withdraw(120, "8765"); Console.WriteLine("Balance is {0:C}", cust.GetCustomerBalance("8765")); }

[Visual Basic] Shared Sub Main() Dim cust As New BankCustomer(1, "Fred") cust.SetCustomerPin("1234", "8765") cust.Deposit(150) cust.Withdraw(120, "8765") Console.WriteLine("Balance is {0:C}", cust.GetCustomerBalance("8765")) End Sub

6. To create a network connection to transmit this object across the network, add statements to perform the following tasks: a. Print the message Press ENTER when the receiver is running to the console. b. Wait for the user to press ENTER. c. Create a NetworkStream object by calling the static (C#) or Shared (Visual Basic) Client.Connect method (Client is one of the helper classes in the NetworkLib class library). Your code should resemble the statements that appear in bold in the following examples.
[Visual C#] static void Main(string[] args) { ... Console.WriteLine("Press ENTER when the receiver is running"); Console.ReadLine(); NetworkStream networkStream = Client.Connect(); }

[Visual Basic] Shared Sub Main() ... Console.WriteLine("Press ENTER when the receiver is running") Console.ReadLine() Dim networkStream As NetworkStream = Client.Connect() End Sub

Lab Answer Key for Module 6: Serializing Data

7. Serialize and transmit the BankCustomer object over the network connection by adding code to perform the following tasks: a. Create a BinaryFormatter object. b. Call the Serialize method of the BinaryFormatter object, and then specify the NetworkStream object and the BankCustomer object as parameters. c. Close the NetworkStream object. d. Display the message Customer data sent on the console. Your code should resemble the statements that appear in bold in the following examples.
[Visual C#] static void Main(string[] args) { ... BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(networkStream, cust); networkStream.Close(); Console.WriteLine("Customer data sent"); }

[Visual Basic] Shared Sub Main() ... Dim formatter As New BinaryFormatter() formatter.Serialize(networkStream, cust) networkStream.Close() Console.WriteLine("Customer data sent") End Sub

8. Build the solution, and then correct any compiler errors.

Task 3: Deserialize customer information received in binary format


1. In Solution Explorer, right-click the Receiver project, and then add references to the Bank and NetworkLib projects. 2. In the Receiver project, open the Program.cs file (if you are using Visual C#) or the Program.vb file (if you are using Visual Basic). 3. At the top of the file, add statements to bring the System.Runtime.Serialization.Formatters.Binary, System.Net.Sockets, NetworkLib, and Bank namespaces into scope.
Note: If you are using Visual Basic, you must import the NetworkLib.NetworkLib and Bank.Bank namespaces.

Lab Answer Key for Module 6: Serializing Data

Your code should resemble the statements in the following examples.


[Visual C#] using System.Runtime.Serialization.Formatters.Binary; using System.Net.Sockets; using NetworkLib; using Bank;

[Visual Imports Imports Imports Imports

Basic] System.Runtime.Serialization.Formatters.Binary System.Net.Sockets NetworkLib.NetworkLib Bank.Bank

4. In the Program class, in the Main method, add code to display the message Receiver is running to the console. Your code should resemble the statement that appears in bold in the following examples.
[Visual C#] static void Main(string[] args) { Console.WriteLine("Receiver is running"); }

[Visual Basic] Shared Sub Main() Console.WriteLine("Receiver is running") End Sub

5. Create a NetworkStream object that receives data from the sender by calling the static (C#) or Shared (Visual Basic) Server.Listen method (Server is another helper class in the NetworkLib class library). Your code should resemble the statement that appears in bold in the following examples.
[Visual C#] static void Main(string[] args) { ... NetworkStream networkStream = Server.Listen(); }

[Visual Basic] Shared Sub Main() ...

Lab Answer Key for Module 6: Serializing Data

Dim networkStream As NetworkStream = Server.Listen() End Sub

6. Receive and deserialize the BankCustomer object from the network by performing the following tasks: a. Create a BinaryFormatter object. b. Call the Deserialize method of the BinaryFormatter object, specify the NetworkStream object as the parameter, and then convert the value that is returned into a BankCustomer object. c. Close the NetworkStream object. Your code should resemble the statements that appear in bold in the following examples.
[Visual C#] static void Main(string[] args) { ... BinaryFormatter formatter = new BinaryFormatter(); BankCustomer cust = formatter.Deserialize(networkStream) as BankCustomer; networkStream.Close(); }

[Visual Basic] Shared Sub Main() ... Dim formatter As New BinaryFormatter() Dim cust As BankCustomer = formatter.Deserialize(networkStream) networkStream.Close() End Sub

7. To verify that the BankCustomer object has been received successfully, add statements to perform the following tasks (remember that the PIN for this customer is the string 8765). a. Display the ID and name of the customer and the current balance of the account. b. Deposit 20 into the account. c. Withdraw 30 from the account. d. Display the new balance. Your code should resemble the statements that appear in bold in the following examples.
[Visual C#] static void Main(string[] args)

Lab Answer Key for Module 6: Serializing Data

{ ... Console.WriteLine("ID:{0}, Name:{1}, Balance:{2:C}", cust.CustomerID, cust.CustomerName, cust.GetCustomerBalance("8765")); cust.Deposit(20); cust.Withdraw(30, "8765"); Console.WriteLine("New balance:{0:C}", cust.GetCustomerBalance("8765")); }

[Visual Basic] Shared Sub Main() ... Console.WriteLine("ID:{0}, Name:{1}, Balance:{2:C}", cust.CustomerID, cust.CustomerName, cust.GetCustomerBalance("8765")) cust.Deposit(20) cust.Withdraw(30, "8765") Console.WriteLine("New balance:{0:C}", cust.GetCustomerBalance("8765")) End Sub

8. Build the solution, and then correct any compiler errors.

Task 4: Test the solution


1. In Solution Explorer, right-click the Serializer solution, click Set Startup Projects, and then verify that the Receiver and Sender projects are configured to start when you run the solution (if they are not, click Multiple startup projects, set the Action for both projects to Start, and set the Action for the Bank and NetworkLib projects to None). Close the Solution Serializer Property Pages window. 2. Start the solution without debugging, and then move the console windows for the Sender and Receiver applications so that they are both visible. 3. In the Sender console window, verify that it displays the balance as 30, and then press ENTER. 4. In the Receiver console window, verify that it displays a customer ID of 1, a name of Fred, a balance of 30, and a new balance of 20 (after the deposit and withdraw operations have completed). 5. Close both console windows.
Note: This exercise has shown you how to send serialized data over a network, but you can use exactly the same technique to serialize data to a file by creating and using a FileStream object rather than a NetworkStream object.

Lab Answer Key for Module 6: Serializing Data

Exercise 2 Customizing the Runtime Serialization Process


Task 1: Implement the GetObjectData method of the ISerializable interface
1. Open the Serializer solution in the E:\Labfiles\Starter\CS\Ex2\Serializer folder (if you are using Visual C#) or the E:\Labfiles\Starter\VB\Ex2\Serializer folder (if you are using Visual Basic). This solution contains an additional class library project that is called EncryptionLib. This class contains a helper class that is called EncryptionHelper that provides static (C#) or Shared (Visual Basic) methods to generate a public/private key pair and for encrypting and decrypting data by using this key pair. 2. In Solution Explorer, right-click the Bank project, and then add a reference to the EncryptionLib project. 3. In the Bank.cs file (if you are using Visual C#) or the Bank.vb file (if you are using Visual Basic), add a statement to bring the System.Runtime.Serialization, System.Text, System.Security.Cryptography, and EncryptionLib namespaces into scope.
Note: If you are using Visual Basic, you must import the EncryptionLib.EncryptionLib namespace.

Your code should resemble the statements in the following examples.


[Visual C#] using System.Runtime.Serialization; using System.Text; using System.Security.Cryptography; using EncryptionLib;

[Visual Imports Imports Imports Imports

Basic] System.Runtime.Serialization System.Text System.Security.Cryptography EncryptionLib.EncryptionLib

4. Modify the definition of the BankCustomer class, and specify that it implements the ISerializable interface. Your code should resemble the statement that appears in bold in the following examples.
[Visual C#] class BankCustomer : ISerializable

10

Lab Answer Key for Module 6: Serializing Data

{ ... }

[Visual Basic] Class BankCustomer Implements ISerializable ... End Class

5. Add a public void (Sub) method that is called GetObjectData to the BankCustomer class. This method implements the method definition that is specified in the ISerializable interface and takes two parameters: a SerializationInfo object that is called info and a StreamingContext object that is called context. Your code should resemble the statements in the following examples.
[Visual C#] public void GetObjectData(SerializationInfo info, StreamingContext context) { }

[Visual Basic] Public Sub GetObjectData(ByVal info As SerializationInfo, ByVal context As StreamingContext) _ Implements ISerializable.GetObjectData End Sub

6. In the GetObjectData method, add code to encrypt the data in the pin field of the BankCustomer object by performing the following tasks: a. Create an RSAParameters object that is called publicKey, and initialize it by calling the static (C#) or Shared (Visual Basic) EncryptionHelper.GetPublicKey method. b. Create a byte array that is called pinData, and populate it with the data in the pin field of the BankCustomer object converted into an array of Unicode characters by calling the static (C#) or Shared (Visual Basic) Encoding.Unicode.GetBytes method. c. Call the static (C#) or Shared (Visual Basic) EncryptionHelper.EncryptData method. Pass the pinData and publicKey variables as parameters. Store the return value in another byte array that is called encryptedPin.

Lab Answer Key for Module 6: Serializing Data

11

Your code should resemble the statements that appear in bold in the following examples.
[Visual C#] public void GetObjectData(SerializationInfo info, StreamingContext context) { RSAParameters publicKey = EncryptionHelper.GetPublicKey(); byte[] pinData = Encoding.Unicode.GetBytes(pin); byte[] encryptedPin = EncryptionHelper.EncryptData(pinData, publicKey); }

[Visual Basic] Public Sub GetObjectData(ByVal info As SerializationInfo, ByVal context As StreamingContext) _ Implements ISerializable.GetObjectData Dim publicKey As RSAParameters = EncryptionHelper.GetPublicKey() Dim pinData() As Byte = Encoding.Unicode.GetBytes(pin) Dim encryptedPin() As Byte = EncryptionHelper.EncryptData(pinData, publicKey) End Sub

7. In the GetObjectData method, add code to store each of the items that is shown in the following table into the SerializationInfo object that was passed in as a parameter, by calling the AddValue method. Specify the value in the Name column as the first parameter and the object in the Item column as the second parameter.
Name "id" "name" "balance" "pin" Item id name balance encryptedPin

Your code should resemble the statements that appear in bold in the following examples.
[Visual C#] public void GetObjectData(SerializationInfo info, StreamingContext context) { ... info.AddValue("id", id); info.AddValue("name", name); info.AddValue("balance", balance); info.AddValue("pin", encryptedPin); }

12

Lab Answer Key for Module 6: Serializing Data

[Visual Basic] Public Sub GetObjectData(ByVal info As SerializationInfo, ByVal context As StreamingContext) _ Implements ISerializable.GetObjectData ... info.AddValue("id", id) info.AddValue("name", name) info.AddValue("balance", balance) info.AddValue("pin", encryptedPin) End Sub

8. Build the solution, and then correct any compiler errors.

Task 2: Implement a deserialization constructor


1. Add a private constructor to the BankCustomer class. The constructor takes two parameters: a SerializationInfo object that is called info and a StreamingContext object that is called context. Your code should resemble the statements in the following examples.
[Visual C#] private BankCustomer(SerializationInfo info, StreamingContext context) { }

[Visual Basic] Private Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext) End Sub

2. In the constructor, add code to retrieve the data from the SerializationInfo object and populate the BankCustomer object by performing the following tasks: a. Call the GetInt32 method of the info object, passing the string id as the parameter, and storing the result in the id field of the BankCustomer object. b. Call the GetString method of the info object, passing the string name as the parameter, and storing the result in the name field of the BankCustomer object. c. Call the GetDecimal method of the info object, passing the string balance as the parameter, and storing the result in the balance field of the BankCustomer object. d. Create a byte array that is called encryptedPin, and call the GetValue method of the info object, passing the string pin and the byte array type as parameters. Store the result in the encryptedPin object.

Lab Answer Key for Module 6: Serializing Data

13

e. Print the data in the encryptedPin object to the console window to enable you to verify that the data is encrypted when you test the solution.
Note: You can convert the data in the encryptedPin byte array into a string by using the static (Shared) Encoding.Unicode.GetString method.

Your code should resemble the statements that appear in bold in the following examples.
[Visual C#] private BankCustomer(SerializationInfo info, StreamingContext context) { id = info.GetInt32("id"); name = info.GetString("name"); balance = info.GetDecimal("balance"); byte[] encryptedPin = info.GetValue("pin", typeof(byte[])) as byte[]; Console.WriteLine("In deserialization constructor: Encrypted pin is {0}", Encoding.Unicode.GetString(encryptedPin)); }

[Visual Basic] Private Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext) id = info.GetInt32("id") name = info.GetString("name") balance = info.GetDecimal("balance") Dim encryptedPin() As Byte = info.GetValue("pin", GetType(Byte())) Console.WriteLine("In deserialization constructor: Encrypted pin is {0}", Encoding.Unicode.GetString(encryptedPin)) ) End Sub

3. In the constructor, add code to decrypt the encrypted PIN by performing the following tasks: a. Create an RSAParameters object that is called privateKey, and initialize it by calling the static (C#) or Shared (Visual Basic) EncryptionHelper.GetPrivateKey method. b. Create a byte array that is called decryptedPin, and call the static (C#) or Shared (Visual Basic) EncryptionHelper.DecryptData method. Pass the encryptedPin and privateKey objects as parameters. Store the return value in the decryptedPin variable. c. Convert the decryptedPin byte array into a string by calling the static (C#) or Shared (Visual Basic) Encoding.Unicode.GetString method. Store the result in the pin field of the BankCustomer object.

14

Lab Answer Key for Module 6: Serializing Data

d. Print the data in the pin field to the console window to enable you to verify that the data is successfully decrypted when you test the solution. Your code should resemble the statements that appear in bold in the following examples.
[Visual C#] public void BankCustomer(SerializationInfo info, StreamingContext context) { ... RSAParameters privateKey = EncryptionHelper.GetPrivateKey(); byte[] decryptedPin = EncryptionHelper.DecryptData(encryptedPin, privateKey); pin = Encoding.Unicode.GetString(decryptedPin); Console.WriteLine("In deserialization constructor: Decrypted pin is {0}", pin); }

[Visual Basic] Private Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)

... Dim privateKey As RSAParameters = EncryptionHelper.GetPrivateKey() Dim decryptedPin() As Byte = EncryptionHelper.DecryptData(encryptedPin, privateKey) pin = Encoding.Unicode.GetString(decryptedPin) Console.WriteLine("In deserialization constructor: Decrypted pin is {0}", pin) End Sub

4. Build the solution, and then correct any compiler errors.

Task 3: Test the solution


1. In Solution Explorer, right-click the Serializer solution, click Set Startup Projects, and then verify that the Receiver and Sender projects are configured to start when you run the solution (if they are not, click Multiple startup projects, set the Action for both projects to Start, and set the Action for the Bank, NetworkLib, and EncryptionLib projects to None). Close the Solution Serializer Property Pages window. 2. Start the solution without debugging, and then move the console windows for the Sender and Receiver applications so that they are both visible. 3. In the Sender console window, verify that it displays the balance as 30, and then press ENTER. 4. In the Receiver console window, verify that it displays an encrypted PIN (it will appear as a series of characters, many of which are unprintable and displayed as ? characters), a decrypted PIN of 8765, a customer ID of 1, a name of Fred, a balance

Lab Answer Key for Module 6: Serializing Data

15

of 30, and a new balance of 20 (after the deposit and withdraw operations have completed). 5. Close both console windows.

Exercise 3 Serializing and Deserializing Data As XML


Task 1: Modify the BankCustomer class to support XML serialization
1. Open the Serializer solution in the E:\Labfiles\Starter\CS\Ex3\Serializer folder (if you are using Visual C#) or the E:\Labfiles\Starter\VB\Ex3\Serializer folder (if you are using Visual Basic). 2. In the Bank.cs file (if you are using Visual C#) or the Bank.vb file (if you are using Visual Basic), remove the following items from the BankCustomer class because they are not required to implement XML serialization: a. The SerializableAttribute attribute. b. The reference to the ISerializable interface in the class definition. c. The GetObjectData method. d. The deserialization constructor. 3. Add a default constructor to the BankCustomer class. In the body of this constructor, add code to initialize the fields in the object by using the values in the following table.
Field id name balance pin Value 0 String.Empty 0 String.Empty

Your code should resemble the statements in the following examples.


[Visual C#] public BankCustomer() { id = 0; name = String.Empty; balance = 0; pin = String.Empty; }

[Visual Basic] Public Sub New() id = 0

16

Lab Answer Key for Module 6: Serializing Data

name = String.Empty balance = 0 pin = String.Empty End Sub

4. Build the solution, and then correct any compiler errors.

Task 2: Modify the Sender and Receiver applications to transmit data as XML
1. In the Sender project, in the Program.cs file (if you are using Visual C#) or the Program.vb file (if you are using Visual Basic), add a statement to the top of the file to bring the System.Xml.Serialization namespace into scope. Your code should resemble the statement in the following examples.
[Visual C#] using System.Xml.Serialization;

[Visual Basic] Imports System.Xml.Serialization

2. In the Program class, near the end of the Main method, remove the two statements that appear in bold in the following examples.
[Visual C#] static void Main(string[] args) { ... BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(networkStream, cust); networkStream.Close(); Console.WriteLine("Customer data sent"); }

[Visual Basic] Shared Sub Main() ... Dim formatter As New BinaryFormatter() formatter.Serialize(networkStream, cust) networkStream.Close() Console.WriteLine("Customer data sent" End Sub

Lab Answer Key for Module 6: Serializing Data

17

3. Serialize and transmit the BankCustomer object as XML by adding code to perform the following tasks, and replace the code that you deleted in the previous step: a. Create an XmlSerializer object, specifying the type of the BankCustomer class as the parameter to the constructor. b. Call the Serialize method of the XmlSerializer object, specifying the NetworkStream object and the BankCustomer object as parameters. Your code should resemble the statements that appear in bold in the following examples.
[Visual C#] static void Main(string[] args) { ... XmlSerializer serializer = new XmlSerializer(typeof(BankCustomer)); serializer.Serialize(networkStream, cust); networkStream.Close(); Console.WriteLine("Customer data sent"); }

[Visual Basic] Shared Sub Main() ... Dim serializer As New XmlSerializer(GetType(BankCustomer)) serializer.Serialize(networkStream, cust) networkStream.Close() Console.WriteLine("Customer data sent") End Sub

4. In the Receiver project, in the Program.cs file (if you are using Visual C#) or the Program.vb file (if you are using Visual Basic), add a statement to the top of the file to bring the System.Xml.Serialization namespace into scope. Your code should resemble the statement in the following examples.
[Visual C#] using System.Xml.Serialization;

[Visual Basic] Imports System.Xml.Serialization

5. In the Program class, in the Main method, remove the two statements that appear in bold in the following examples.
[Visual C#] static void Main(string[] args) {

18

Lab Answer Key for Module 6: Serializing Data

... NetworkStream networkStream = Server.Listen(); BinaryFormatter formatter = new BinaryFormatter(); BankCustomer cust = formatter.Deserialize(networkStream) as BankCustomer; networkStream.Close(); ... }

[Visual Basic] Public Shared Sub Main() ... Dim NetworkStream As NetworkStream = Server.Listen() Dim formatter As New BinaryFormatter() Dim cust As BankCustomer = formatter.Deserialize(NetworkStream) NetworkStream.Close() ... End Sub

6. Receive and deserialize the BankCustomer object from the network by performing the following tasks: a. Create an XmlSerializer object and specify the type of the BankCustomer class as the parameter to the constructor. b. Call the Deserialize method of the XmlSerializer object, specifying the NetworkStream object as the parameter, and converting the value that is returned into a BankCustomer object. Your code should resemble the statements that appear in bold in the following examples.
[Visual C#] static void Main(string[] args) { ... NetworkStream networkStream = Server.Listen(); XmlSerializer serializer = new XmlSerializer(typeof(BankCustomer)); BankCustomer cust = serializer.Deserialize(networkStream) as BankCustomer; networkStream.Close(); ... }

[Visual Basic] Public Shared Sub Main() ...

Lab Answer Key for Module 6: Serializing Data

19

Dim NetworkStream As NetworkStream = Server.Listen() Dim serializer As New XmlSerializer(GetType(BankCustomer)) Dim cust As BankCustomer = serializer.Deserialize(NetworkStream) networkStream.Close() ... End Sub

7. Build the solution, and then correct any compiler errors. 8. In Solution Explorer, right-click the Serializer solution, click Set Startup Projects, and then verify that the Receiver and Sender projects are configured to start when you run the solution (if they are not, click Multiple startup projects, set the Action for both projects to Start, and set the Action for the Bank and NetworkLib projects to None). Close the Solution Serializer Property Pages window. 9. In the Receiver project, in the Main method of the Program class, set a breakpoint on the statement in the following examples.
[Visual C#] static void Main(string[] args) { ... networkStream.Close(); ... }

[Visual Basic] Public Shared Sub Main() ... networkStream.Close() ... End Sub

10. Start the solution in debug mode, and then move the console windows for the Sender and Receiver applications so that they are both visible. 11. In the Sender console window, verify that it displays the balance as 30, and then press ENTER. Visual Studio stops at the breakpoint in the Main method of the Receiver application. 12. In Visual Studio, in the Autos window, expand the cust object. Verify that the fields and properties in this object have the values in the following table.
Field/property balance CustomerID Value 0D 0

20

Lab Answer Key for Module 6: Serializing Data

Field/property CustomerName id name pin

Value "" 0 "" ""

Note: The fields in the BankCustomer class are all private, and the only public properties are read-only. By default, the XmlSerializer class does not serialize or deserialize private fields, and it cannot use read-only properties to populate an object. Consequently, the fields are all initialized to the values that are assigned in the default constructor. However, you can modify the way in which XML serialization occurs by implementing the IXmlSerializable interface in the BankCustomer class.

13. Stop debugging.

Task 3: Implement the IXmlSerializable interface and customize the XML serialization process
1. In the Bank.cs file (if you are using Visual C#) or the Bank.vb file (if you are using Visual Basic), add a statement to the top of the file to bring the System.Xml.Serialization, System.Xml.Schema, and System.Xml namespaces into scope. Your code should resemble the statements in the following examples.
[Visual C#] using System.Xml.Serialization; using System.Xml.Schema; using System.Xml;

[Visual Imports Imports Imports

Basic] System.Xml.Serialization System.Xml.Schema System.Xml

2. Modify the definition of the BankCustomer class to implement the IXmlSerializable interface. Your code should resemble the statement that appears in bold in the following examples.
[Visual C#] class BankCustomer : IXmlSerializable { ... }

Lab Answer Key for Module 6: Serializing Data

21

[Visual Basic] Class BankCustomer Implements IXmlSerializable ... End Class

3. Add a public method that is called GetSchema to the BankCustomer class. This method takes no parameters and returns an XmlSchema object. This method implements the method definition that is specified in the IXmlSerializable interface. In the body of this method, add a statement to return a null (Nothing) object. Your code should resemble the statements in the following examples.
[Visual C#] public XmlSchema GetSchema() { return null; }

[Visual Basic] Public Function GetSchema() As XmlSchema _ Implements IXmlSerializable.GetSchema Return Nothing End Function

Note: The GetSchema method of the IXmlSerializable interface is currently reserved and should always return a null (Nothing) value.

4. Add a public void (Sub) method that is called WriteXml to the BankCustomer class. This method takes an XmlWriter object that is called writer as a parameter. This method also implements the method definition that is specified in the IXmlSerializable interface. Your code should resemble the statements in the following examples.
[Visual C#] public void WriteXml(XmlWriter writer) { }

[Visual Basic] Public Sub WriteXml(ByVal writer As XmlWriter) _ Implements IXmlSerializable.WriteXml End Sub

22

Lab Answer Key for Module 6: Serializing Data

5. In the WriteXml method, add code to write the names and values of the four fields, id, name, balance, and pin, to the XmlWriter object. Output these fields as XML elements by using the WriteElementString method. You convert the values in the id and balance fields to strings before you output them. Your code should resemble the statements that appear in bold in the following examples.
[Visual C#] public void WriteXml(XmlWriter writer) { writer.WriteElementString("id", id.ToString()); writer.WriteElementString("name", name); writer.WriteElementString("balance", balance.ToString()); writer.WriteElementString("pin", pin); }

[Visual Basic] Public Sub WriteXml(ByVal writer As XmlWriter) _ Implements IXmlSerializable.WriteXml writer.WriteElementString("id", id.ToString()) writer.WriteElementString("name", name) writer.WriteElementString("balance", balance.ToString()) writer.WriteElementString("pin", pin) End Sub

Note: This implementation of the WriteXml method serializes the PIN in its original unencrypted format. If you must encrypt this data, you can use the technique that was shown in Exercise 2.

6. Add a public void (Sub) method that is called ReadXml to the BankCustomer class. This method takes an XmlReader object that is called reader as a parameter. This method also implements the method definition that is specified in the IXmlSerializable interface.

Your code should resemble the statements in the following examples.


[Visual C#] public void ReadXml(XmlReader reader) { }

[Visual Basic] Public Sub ReadXml(ByVal reader As XmlReader) _

Lab Answer Key for Module 6: Serializing Data

23

Implements IXmlSerializable.ReadXml End Sub

7. In the ReadXml method, add code to read each element from the XmlReader object and use these elements to populate the four fields, id, name, balance, and pin, by performing the following tasks: a. Use the Read method of the XmlReader object to skip to the first element. b. Call the ReadStartElement method of the XmlReader object and specify the string id as the parameter to read the opening XML tag for the id element in the XML stream. c. Call the ReadContentAsInt method of the XmlReader object to read the data in the id element and convert it to an integer value. Store the value that is returned in the id field of the BankCustomer object. d. Call the ReadEndElement method of the XmlReader object to read the closing XML tag for the id element in the XML stream. e. Repeat Steps b to d for the name, balance, and pin elements. Use the ReadString method to read the data for the name and pin elements, and the ReadContentAsDecimal method to read the data for the balance element. Your code should resemble the statements in the following examples.
[Visual C#] public void ReadXml(XmlReader reader) { reader.Read(); reader.ReadStartElement("id"); id = reader.ReadContentAsInt(); reader.ReadEndElement(); reader.ReadStartElement("name"); name = reader.ReadString(); reader.ReadEndElement(); reader.ReadStartElement("balance"); balance = reader.ReadContentAsDecimal(); reader.ReadEndElement(); reader.ReadStartElement("pin"); pin = reader.ReadString(); reader.ReadEndElement(); }

[Visual Basic] Public Sub ReadXml(ByVal reader As XmlReader) _ Implements IXmlSerializable.ReadXml reader.Read()

24

Lab Answer Key for Module 6: Serializing Data

reader.ReadStartElement("id") id = reader.ReadContentAsInt() reader.ReadEndElement() reader.ReadStartElement("name") name = reader.ReadString() reader.ReadEndElement() reader.ReadStartElement("balance") balance = reader.ReadContentAsDecimal() reader.ReadEndElement() reader.ReadStartElement("pin") pin = reader.ReadString() reader.ReadEndElement() End Sub

8. Build the solution, and then correct any compiler errors.

Task 4: Test the solution


1. Start the solution in debug mode, and then move the console windows for the Sender and Receiver applications so that they are both visible. 2. In the Sender console window, verify that it displays the balance as 30, and then press ENTER. Visual Studio stops at the breakpoint in the Main method of the Receiver application. 3. In Visual Studio, in the Autos window, expand the cust object. Verify that the fields and properties in this object have the values in the following table.
Field/property balance CustomerID CustomerName id name pin Value 30D 1 "Fred" 1 "Fred" "8765"

4. Step through the remaining statements of the application and verify that it displays a customer ID of 1, a name of Fred, a balance of 30, and a new balance of 20 (after the deposit and withdraw operations have completed) in the console window. 5. Close Visual Studio.

Anda mungkin juga menyukai