Use the XmlSerializer class to serialize objects to XML format save _ Support generics dictionary

Source: Internet
Author: User
Tags serialization

In a particular application, we need to persist an object in memory that is instantiated from a template class and cannot be saved to a database, where only the template for this object is stored.

Because of the use of dictionary to generics, while XmlSerializer does not support the default generic dictionary, I have found some information and implemented in three different ways in this article. The Convention in this article:

Scenario 1: Dictionary of Non-serialized generics

Scenario 2: Define a dictionary that supports generics

Scenario 3: Let each class implement the IXmlSerializable interface

Article content:
1. Class diagram and the association between classes
2. Scenario 1: Dictionary of Non-serialized generics
3. Option 2: Define a dictionary that supports generics
4. Option 3: Let each class implement the IXmlSerializable interface
5. Summary


1. Class diagram and the association between classes

Compensation template Paytemplate, it through the dictionary<int, payitemtemplate> maintain a number of compensation column template payitemtemplate.

And a payitemtemplate through Dictionary<int, Payitemtemplate> records the payitemtemplate that used it.

Therefore, paytemplate and payitemtemplate are a pair of multiple associations; The payitemtemplate is a one-to-many self-association.

The class associations in scenario 1,2,3 are similar, and there is no repetition here. Detailed differences can be downloaded from the source code view at the end of this article.



2. Scenario 1: Dictionary of Non-serialized generics
Now that we know that generics dictionary are not supported by XmlSerializer, we avoid the dictionary of generics being serialized, just add xmlignore properties to the field. The code is as follows:

[XmlIgnore]//With XmlIgnore, which indicates serialization does not serialize this property

Dictionary<int Public, payitemtemplate> payitemtemplatedic

48 {

payitemtemplates {return;}

set {payitemtemplates = value;}

51}

OK, so what if we let the generics dictionary not be serialized, and we need to serialize the objects in the generic dictionary to the XML to save them? The idea here is to add an extra payitemtemplate[] array field, The code implementation is as follows:

///<summary>

54///for serialization of Payitemtemplate collections

///</summary>

Payitemtemplates Public payitemtemplate[]

57 {

The Get

59 {

list<payitemtemplate> List = new list<payitemtemplate> (payitemtemplates.count);

Payitemtemplates foreach (keyvaluepair<int,payitemtemplate> pit in)

62 {

The list. ADD (Pit. Value);

64}

65

The return list. ToArray ();

67}

Set

69 {

Payitemtemplates = new Dictionary<int, payitemtemplate> ();

A foreach (Payitemtemplate pit in value)

72 {

Payitemtemplates.add (Pit. Id, Pit);

74}

75}

76}

This is what we need to do, the following tests, specific unit tests, can be viewed in the download source code.
Test results:
Forward Serialization:

<?xml version= "1.0" encoding= "Utf-8"?>

<paytemplate xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd= "Http://www.w3.org/2001/XMLSchema" >

<Id>100</Id>

<Name> Compensation Template Test</name>

<StartDate>2007-08-16T19:10:43.640625+08:00</StartDate>

<PayItemTemplates>

<PayItemTemplate>

<numbericalCategory>Calculational</numbericalCategory>

<NumbericalCategory>Calculational</NumbericalCategory>

<Id>10000</Id>

<Name> Compensation Template Column 1</name>

<PayItemTemplateRelieds>

<PayItemTemplate>

<numbericalCategory>Calculational</numbericalCategory>

<NumbericalCategory>Calculational</NumbericalCategory>

<Id>20000</Id>

<Name> Compensation Template Column 2</name>

<payitemtemplaterelieds/>

<Enabled>true</Enabled>

<Expression>Expression2</Expression>

</PayItemTemplate>

</PayItemTemplateRelieds>

<Enabled>true</Enabled>

<Expression>Expression</Expression>

</PayItemTemplate>

<PayItemTemplate>

<numbericalCategory>Calculational</numbericalCategory>

<NumbericalCategory>Calculational</NumbericalCategory>

<Id>20000</Id>

<Name> Compensation Template Column 2</name>

<payitemtemplaterelieds/>

<Enabled>true</Enabled>

<Expression>Expression2</Expression>

</PayItemTemplate>

</PayItemTemplates>

<WorkFlowCategory>Simple</WorkFlowCategory>

</PayTemplate>

Reverse Serialization:

Scenario 1 Pros and Cons: No additional objects are defined, but extra fields appear (superfluous because this field only appears for serialization).


3. Option 2: Define a dictionary that supports generics

Can the generics dictionary be properly serialized? Yes, redefine a generic serializabledictionary, let it inherit the generics dictionary in. Net and implement the IXmlSerializable interface, the implementation reference in this article is from XML Serializable Generic Dictionary. Two key methods in the IXmlSerializable interface:

///<summary>

26///of anti-serialization

///</summary>

///<param name= "Reader" ></param>

public void ReadXml (XmlReader reader)

30 {

XmlSerializer Keyserializer = new XmlSerializer (typeof (TKey));

XmlSerializer ValueSerializer = new XmlSerializer (typeof (TValue));

-If reader. isemptyelement | | !reader. Read ())

34 {

return;

36}

37

While reader. NodeType!= xmlnodetype.endelement)

39 {

Reader. Readstartelement ("item");

41

The reader. Readstartelement ("key");

TKey key = (TKey) keyserializer.deserialize (reader);

Reader. Readendelement ();

45

Reader. Readstartelement ("value");

TValue value = (TValue) valueserializer.deserialize (reader);

Reader. Readendelement ();

49

Reader. Readendelement ();

The reader. MoveToContent ();

52

this. ADD (key, value);

54}

Reader. Readendelement ();

56}

57

///<summary>

59 Serialization of///

///</summary>

///<param name= "Writer" ></param>

The public void WriteXml (XmlWriter writer)

63 {

XmlSerializer Keyserializer = new XmlSerializer (typeof (TKey));

XmlSerializer ValueSerializer = new XmlSerializer (typeof (TValue));

66

TKey foreach (this. Keys)

68 {

Writer. WriteStartElement ("item");

70

Writer. WriteStartElement ("key");

Keyserializer.serialize (writer, key);

Writer. WriteEndElement ();

74

Writer. WriteStartElement ("value");

Valueserializer.serialize (writer, This[key]);

Writer. WriteEndElement ();

78

Writer. WriteEndElement ();

80}

81}



Complete code check in the source file.

Test results:
Forward Serialization:

<?xml version= "1.0" encoding= "Utf-8"?>

<paytemplatev2 xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd= "Http://www.w3.org/2001/XMLSchema" >

<Id>100</Id>

<Name> Compensation Template Test</name>

<StartDate>2007-08-16T19:08:45.0625+08:00</StartDate>

<PayItemTemplates>

<item>

<key>

<int>10000</int>

</key>

<value>

<PayItemTemplateV2>

<numberic

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.