This article is a continuation of the previous article. If you want to see it from the previous article, click here to go to the previous article.
In the previous article, when netdatacontractserializer is used to serialize objects, many additional attributes will be added to XML. Some of these attributes are used to improve the type information of the serialized content, such as Z: type and Z: assembly. The other role of the attribute is bought by the lower user and left it here for explanation ~.
Let's start with an example. Here we make some extensions to the previous example:
Namespace Serviceinterface
{
[Datacontract]
Public Class Sub
{
Public Sub ()
{}
Public Sub ( Int ID, String Name)
{
ID=ID;
Name=Name;
}
[Datamember]
Public Int ID;
[Datamember]
Public String Name;
}
[Datacontract]
Public Class Root
{
Public Root ()
{}
Public Root ( Int ID, String Name, sub)
{
ID=ID;
Name=Name;
Sub1=Sub;
Sub2=Sub;
}
[Datamember]
Public Int ID;
[Datamember]
Public String Name;
[Datamember]
Public Sub sub1;
[Datamember]
Public Sub sub2;
}
}
Compared with the previous example, there is a root class, and this root class has two members, sub1 and sub2, both of which are of the sub type. What is this? Then I can see it ~
We still use datacontractserializer to serialize the root object, but this is somewhat different from the previous one. After serialization, We deserialize it back:
Sub = New Sub ( 10 , " Ten " );
Root = New Root ( 100 , " Root " , Sub );
Datacontractserializer DCS = New Datacontractserializer ( Typeof (Root ));
Memorystream stream = New Memorystream ();
DCs. writeobject (stream, root );
Byte [] Buf = Stream. toarray ();
String Str = Encoding. utf8.getstring (BUF, 0 , Buf. Length );
Stream. Seek ( 0 , Seekorigin. Begin );
Root rt1 = (Root) DCS. readobject (Stream );
Execute the above sectionCodeIt can be found that the serialized content is:
< Root Xmlns = "Http://schemas.datacontract.org/2004/07/ServiceInterface" Xmlns: I = "Http://www.w3.org/2001/XMLSchema-instance" >
< ID > 100 </ ID >
< Name > Root </ Name >
< Sub1 >
< ID > 10 </ ID >
< Name > Ten </ Name >
</ Sub1 >
< Sub2 >
< ID > 10 </ ID >
< Name > Ten </ Name >
</ Sub2 >
</ Root >
What about deserialization? Careful XD may have seen some clues ~ What? Didn't you find out? Step debug again to see it?
Right! Before serialization, sub1 and sub2 of the root object reference the same sub object. After deserialization, this field will reference two different objects (although the content is identical )! This is what we got !! How can we tolerate such a situation today! This is not an exaggeration. In this case, the root object references sub and sub references the root object. When a circular reference occurs, datacontractserializer cannot handle this situation. In this case, netdatacontractserializer is useful.
By now, readers can guess what the last unexplained Z: ID means. Yes, it is used to solve the problem of object reference. Use netdatacontractserializer to serialize the above root object and deserialize it:
Netdatacontractserializer NDCs = New Netdatacontractserializer ();
Memorystream nstream = New Memorystream ();
NDCs. writeobject (nstream, root );
Byte [] Nbuf = Nstream. toarray ();
String NSTR = Encoding. utf8.getstring (nbuf, 0 , Nbuf. Length );
Nstream. Seek ( 0 , Seekorigin. Begin );
Root rt2 = (Root) NDCs. readobject (nstream );
The serialized XML is:
< Root Z: ID = "1" Z: Type = "Serviceinterface. Root" Z: Assembly = "Serviceinterface, version = 1.0.0.0, culture = neutral, publickeytoken = NULL" Xmlns = "Http://schemas.datacontract.org/2004/07/ServiceInterface" Xmlns: I = "Http://www.w3.org/2001/XMLSchema-instance" Xmlns: Z = "Http://schemas.microsoft.com/2003/10/Serialization" >
< ID > 100 </ ID >
< Name Z: ID = "2" > Root </ Name >
< Sub1 Z: ID = "3" >
< ID > 10 </ ID >
< Name Z: ID = "4" > Ten </ Name >
</ Sub1 >
< Sub2 Z: ref = "3" I: Nil = "True" />
</ Root >
This time, the deserialized object can be said to be consistent with the original object in both form and semantics. How does it do it? Note: In sub2, the value of Z: ref is 3, while that of sub1 is 3. This means that the deserialization process will create an object for sub1, and sub2 will only reference sub1. Finally, netdatacontractserializer assigns a Z: ID to each referenced object.
The discussion about WCF serialization is here first, but I know that this is just the beginning ~