- Table of Contents
- .NET Book Recommendations
- What Is .NET?
- The Microsoft .NET Framework
- The Common Language Runtime (CLR), the Common Type System (CTS), and the Common Language Specification (CLS)
- .NET Framework Class Library
- Visual Studio .NET
- .NET Enterprise Servers and .NET My Services
- .NET Compliant Languages
- C#
- Visual Basic .NET (VB .NET)
- ASP.NET
- XML Web Services
- ADO.NET
- XML.NET
- Windows Forms
- Why .NET?
- Displaying Errors with the Error Provider
- COM Interoperability
- Comparing Java and .NET
- Calling Unmanaged Code
- .NET Application Security
- Code Access Security
- .NET Standards Support
- Numeric Types in the .NET Framework
- Working with Strings
- Formatting Strings
- Trimming Character Strings
- Comparing Strings in .NET 2.0
- Arrays and Collections
- Arrays as Class Members
- Sorting a Multi-Dimensional Array
- File I/O (System.IO)
- Working with File Names
- Using the File System
- Working with Files and Directories
- Monitoring the File System
- Working with Streams
- Working with Text Encodings
- Working with Date and Time
- Extending the DateTime Class
- Fun with Dates
- Exceptions
- Delegates
- Events
- Asynchronous Programming
- Asynchronous File I/O
- Timers
- Random Numbers
- Serialization
- Serialization Example
- Binary Serialization
- Types of Binary Serialization
- Controlling Binary Serialization
- XML Serialization
- Official Documentation
- MultiThreading (System.Threading)
- Multi-Threading Overview
- The Managed Thread Pool
- Managed Threading
- Thread Synchronization
- Synchronizing Data Access
- Trace Debugging
- Tracing in .NET 2.0
- ASP.NET Trace
- Validating User Input in ASP.NET Web Pages
- Event Logging
- Monitoring Application Performance
- Accessing the Registry
- Accessing Environment Information
- Environment Variables in .NET 2.0
- Managing Windows Forms Applications
- Working with Email
- Working with Graphics
- Animating a Background
- Working with Images
- Drawing Cycloid Curves
- Simulating the Spirograph
- Building International Web Applications
- .NET Compact Framework
- Mobile Web Development with ASP.NET
- Speech Technologies
- Microsoft MapPoint Web Service
- Working with Typed DataSets
- Using Relationships in DataSets
- DataColumn Expressions
- Playing Simple Sounds
- Playing Sounds with .NET 2.0
- Returning an Image in a Web Page
- RSS
- Best Practices Project Structure
- Best Practices Application Blocks
- The Data Access Application Block
- The Exception Management Application Block
- Best Practices — Performance
- Best Practices — Performance and Scalability
- Best Practices - Testing
- Reading the Tea Leaves, 2005
- Predictions: A Look Back at 2005, and a Look Ahead to 2006
- .NET Downloads
- Application Deployment Overview
- Application Deployment — Versioning
- Application Deployment — Version Policy
- Application Deployment — Packaging and Distribution
- .NET Remoting Overview
- A Remoting Demonstration
- Remoting Configuration
- Remoting: Lifetimes and Leases
- Remoting: Other Issues
- Attributes
- Writing Custom Attributes
- Accessing Attributes in Code
- Reflection
- Class Design: Inheritance, Interface, or Composition?
- The TriTryst Game
- Console Applications in .NET 2.0
- New File I/O Methods in .NET 2.0
- Building Projects with MSBuild
- Unmanaged Callbacks in .NET 2.0
- Timer Troubles
- Non-Rectangular Windows Forms
- Windows Forms Transparency
- 10 Things I Hate About Visual Basic
- 10 Things I Hate About C#
- Background Processing with Idle Time
- Scaling Windows Forms
- Reading and Writing Binary Data
- New Memory Management Functions in .NET 2.0
- Compatibility Between .NET 1.1 and .NET 2.0
- Managed Debugging Assistants in .NET 2.0
- XDir: A Program for Viewing Directory Sizes
- The Microsoft.VisualBasic Namespace
- Operator Overloading
- Working with GPS Data
- Hidden Visual Studio Tools
- .NET 3.0
- The .NET 2.0 Stopwatch Class
- Nullable Types
- Drawing Rotated Text
- Unsafe Code
- Other .NET Languages
- Compiler Directives
- Safe Handles
- Predictions, 2007 Edition
- New Features in C# 3.0
- Generics
- Network Client Programming
- On the Misuse of Exceptions
- Maximum Object Size in .NET
- More on Maximum Object Sizes
- Keyed Collection Memory Limitations
- Matching String Endings
- Allocating Small Data Structures
- Grumbling About Limitations
- Some Thoughts on the Nature of What We Do
- Working with Predicates in Collections
- Working with DataReaders
- Outputting XML with XmlWriter
- Writing XML Data
- Working with Compression
- Another Look at Compressed Streams
- Compressing a Very Large File
- Canonical URIs
- Constructing URIs
- Using OneWayAttribute for Remote Calls
- Selecting a Garbage Collector
- Linked List
- Linked List Application - The MRU List
- Auto-implemented Properties in C#
- The HashSet Collection
- Looking Ahead: 2018
- An Experiment in Optimization
- A Larger Integer
- Extension Methods
- Language Integrated Query (LINQ)
- Variable Length Parameter Lists
- The ReaderWriterLockSlim Synchronization Primitive
- Sorting a Text File
- Sorting a Large Text File
- Using ListView with Large Data Sets
- LINQ One-Liners
- Regular Expression Optimization
- Random File I/O
- Computing the Size of a Structure
- More on Computing Structure Sizes
- UnmanagedMemoryStream
- Dynamically Loading Code
- Building a String Table
- Delegates Versus Function Pointers
- Visual Studio Editor Features
- A Simple Profile Timer
- New Features in C# 4.0
- IEnumerator or IList?
- New Features in .NET 4.0
- Set Operations with IEnumerable and HashSet
- Using File Locks
- Extending Object Functionality
- Clearing a HashSet
- When Hash Codes Matter
- Parsing Command Line Options
- Creating a Single-Instance Program
- Asynchronous Windows Forms Events
- The BackgroundWorker Component
- Fixing a Dumb Mistake
- Thinking About Multi-Threaded Programs
- JavaScript Object Notation
- Useful .NET-related Sites
- Markov Models
- Building an Order 0 Markov Model
- Higher Order Markov Models
- Webmaster's Guide to robots.txt
- An Overview of the Parallel Extensions to .NET
- Parallel Extensions Synchronization Objects
- Thread Safe Collections
- A Bug and a Conundrum
- Another Bug and an Answer
- Task Parallel Library
- Good and Bad Ideas in C#
- Parallel LINQ
- Copying Large Files
- Replacing File.Copy
- Learning from Our Mistakes
- Symbolic Links
- There Is No Easy Fix
- Tracking Hurricanes
- Examining Hurricane Data
- Searching for Multiple Strings
- Simple JSON Processing
- Aho-Corasick String Searching
- Writing a Web Crawler New
- Web Crawler Politeness New
- Source Control Management New
- Informit Reference Library
Controlling Binary Serialization
Last updated Feb 23, 2004.
Controlling Binary Serialization
In order for a object to be serialized, its class must be marked with the Serializable attribute. If you attempt to serialize an object whose type is not so marked, a SerializationException will be thrown. If you create a base class that you think might be serialized at some point in the future, or you think derived classes might be serialized, you should mark it with the Serializable attribute. Understand, though, that the Serializable attribute cannot be inherited. That is, if you derive MyClass from BaseClass, you must mark MyClass with the Serializable attribute, even if BaseClass is already so marked.
Because serialization automatically persists the entire object state, including contained objects, the types of any objects that are contained must also be marked with the Serializable attribute.
There are some situations in which you won't want some fields in the object to be serialized. For example, you might write a collection class that optimizes searches by caching the most recent or most commonly-searched items, or perhaps you use lazy evaluation of a particular property's value and you decide that it's reasonable to require re-calculation of the value when the object is reloaded. For example, if you didn't want the teacher field in our Course object to be serialized, you could precede the field with the NonSerialized attribute, like this:
[C#]
[NonSerialized] private string teacher;
[Visual Basic]
<NonSerialized()> Dim teacher As String
The .NET Framework SDK documentation recommends making all security-sensitive fields NonSerialized. Encryption keys, passwords, and other similar information should not normally be serialized. The Security and Serialization topic in the Framework Documentation provides a little more detail on this topic.
If you need tighter control of the serialization process, you can make your object implement the ISerializable and/or the DeserializationCallback interface, depending on what you want to do. The ISerializable interface lets you control the fields that are serialized and the order in which they're stored. In order to implement ISerializable, your object must implement the GetObjectData and a special deserialization constructor. GetObjectData is called when the object is to be serialized, and the special deserialization constructor is called when the object is created upon deserialization. Here's an example that doesn't serialize the courseName or teacher fields:
[C#]
// deserialization constructor
protected Course(SerializationInfo info, StreamingContext context): base()
{
info.GetInt32("id");
info.GetValue("Students", typeof(ArrayList));
}
// ISerializable.GetObjectData
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("id", id);
info.AddValue("Students", studentsList);
}
[Visual Basic]
' deserialization constructor
Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
Me.New(0)
info.GetInt32("id")
info.GetValue("Students", GetType(ArrayList))
End Sub
' ISerializable.GetObjectData
Public Sub GetObjectData(ByVal info As System.Runtime.Serialization.SerializationInfo, _
ByVal context As System.Runtime.Serialization.StreamingContext) _
Implements System.Runtime.Serialization.ISerializable.GetObjectData
info.AddValue("id", id)
info.AddValue("Students", studentsList)
End Sub
It's important that you call the base class constructor in the special serialization constructor. Otherwise, the object will not be fully constructed.
Remember also that you have to mark your class as implementing the ISerializable interface, like this:
[C#]
class Course: ISerializable
[Visual Basic]
<Serializable()> Class Course Implements ISerializable
The Framework Documentation has additional examples of implementing the ISerializable interface. The documentation also includes some important security issues that you should consider when implementing this interface.
The code shown above does not correctly initialize the courseName and teacher fields of the object. You might get away with calling the LoadCourseInfo method at the end of the deserialization constructor, but that's not recommended because there's no guarantee that the object will be fully constructed at that point (the Framework deserialization code might have a few other things to do). A more reliable way to do it is to have the class implement the IDeserializationCallback interface. This interface consists of a single method, OnDeserialization, that is called when the entire object graph has been deserialized. The object is guaranteed to be fully constructed when this method is called. To implement IDeserializationCallback, mark the class as implementing the interface, and then write the OnDeserialization method, like this:
[C#]
// Implement IDeserializationCallback
class Course: ISerializable, IDeserializationCallback
// Implement OnDeserialization
public void OnDeserialization(object sender)
{
LoadCourseInfo();
}
[Visual Basic]
' Implement IDeserializationCallback <Serializable()> Class Course Implements ISerializable, IDeserializationCallback ' Implement OnDeserialization Public Sub OnDeserialization(ByVal sender As Object) _ Implements System.Runtime.Serialization.IDeserializationCallback.OnDeserialization LoadCourseInfo() End Sub
Binary serialization, using either the binary or the SOAP formatter, is the suggested method of persisting object data in .NET applications, provided that you don't need to share the information with non-.NET programs. The built-in capabilities give you much flexibility in how and what information is stored, and with just a little bit of work you can fine-tune your object's stored data. In addition, if you have really special data storage needs, you can create your own formatter class that implements the <t>IRemotingFormatter and <t>IFormatter interfaces, and use it to persist your data.



Account Sign In
View your cart