FIX: BinaryFormatter and .NET Remoting cannot deserialize deeply nested structs (320079)



The information in this article applies to:

  • Microsoft .NET Framework SDK 1.0
  • Microsoft Visual Studio .NET (2002), Professional Edition
  • Microsoft Visual Studio .NET (2002), Enterprise Architect Edition
  • Microsoft Visual Studio .NET (2002), Enterprise Developer Edition
  • Microsoft Visual Studio .NET (2002), Academic Edition

This article was previously published under Q320079

SYMPTOMS

When you try to pass or return a deeply nested struct in a call to a remote object by using .NET Remoting, you may receive a System.Runtime.Serialization.SerializationException that contains the following message:
"Fixing up a partially available ValueType chain is not implemented."
The same exception may be thrown if you try to deserialize such a struct by using the BinaryFormatter object.

This problem occurs when you use BinaryFormatter to deserialize structs that are nested three levels or deeper. This problem also occurs when you use .NET Remoting to pass or return such structs because Remoting uses BinaryFormatter to format parameters.

RESOLUTION

To resolve this problem, do one of the following:
  • Use classes instead of structs.
  • Do not nest structs to depths of three levels or greater.

STATUS

Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article. This bug was corrected in Visual Studio .NET 2003.

MORE INFORMATION

The following nested structs, defined in C#, demonstrate the problem. The structs are nested three level deep.
[Serializable]
public struct TopLevel
{
	public SecondLevel second ;
}
[Serializable]
public struct SecondLevel
{
	public ThirdLevel third ;
}
[Serializable]
public struct ThirdLevel
{
	public int i;
}
				
The following C# sample code fragment, which uses BinaryFormatter, reproduces the problem by serializing and deserializing an instance of the nested structs:
// Initialize the nested structs.
TopLevel tl = new TopLevel(); 	
tl.second  = new SecondLevel ();
tl.second.third = new ThirdLevel ();
tl.second.third.i = 5;
				
Add these lines on top of the C# file:
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
				
Serialize the structs into a stream, and then try to deserialize the structs:
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
formatter.Serialize(stream, tl);
stream.Position = 0;
Object obj = formatter.Deserialize(stream); 
				
You can use BinaryFormatter with .NET Remoting. By default, the Transmission Control Protocol (TCP) channel uses BinaryFormatter. If you pass the same structs to a remote object by using .NET Remoting with binary serialization, then you will experience the same problem.

REFERENCES

For additional information, click the article number below to view the article in the Microsoft Knowledge Base:

310683 HOW TO: Create a Custom Message Formatter by Using Visual C# .NET


Modification Type:MinorLast Reviewed:9/13/2005
Keywords:kbvs2002sp1sweep kbbug kbpending kbRemoting KB320079