Woodjitsu
Woodjitsu

Reputation: 251

Nested class member serialization

I am trying to work out the best way to serialize nested classes without having to serialize the entire nest class member. Assuming the following the classes:

public class ClassA
{
  public decimal ID { get; set; }
}

public class ClassA1 : ClassA
{
  public decimal Name { get; set; }
  public decimal Value { get; set; }
  public decimal Description { get; set; }
}

public class ClassA2 : ClassA
{
  public ClassA1 Details { get; set; }
  public int SomeValue { get; set; }
}

I have a fixed list of objects of type ClassA1 that are stored in a variable of type List.

I also have a list of objects of type ClassA2 that are stored in a variable of type List

What I would like to do is serialize and deserialize my list of ClassA2 objects. Automatic serialization will serialize the entire contents of each ClassA1 object but I only want to serialize and then deserialize the ClassA1.ID member and then retrieve the object reference from my fixed list upon deserialization.

Automatic Serialization gives me this:

...
<ClassA2>
  <ID>IDStringForObjectClassA2</ID>
  <Details>
    <ClassA1>
      <ID>IDStringForObjectOfClassA1</ID>
      <Name>MyNameValue</Name>
      <Value>MyStringValue</Value>
      <Description>MyDescriptionValue</Description>
    </ClassA1>
  </Details>
  <SomeValue>0</SomeValue>
</ClassA2>

The end result I want in my XML is this

...
<ClassA2>
  <ID>IDStringForObjectClassA2</ID>
  <Details>
    <ClassA1>
      <ID>IDStringForObjectOfClassA1</ID>
    </ClassA1>
  </Details>
  <SomeValue>0</SomeValue>
</ClassA2>

and on deserialization of the ClassA1.ID member, I want to locate a an actual object within a preloaded list

EDIT: Document serializer class below

public class Document
{
  private _ClassA2;

  public Document() { _ClassA2 = null; }

  public ClassA2 ClassA2
  {
    get { return _ClassA2; }
    set { _ClassA2 = value; }
  }

  public string Serialize(StreamWriter writer)
  {
    var serializer = new XmlSerializer(typeof(ClassA2));
    serializer.Serialize(writer, this);
    return writer.ToString();
  }

  public static ClassA2 DeSerialize(StreamReader reader)
  {
    var serializer = new XmlSerializer(typeof(ClassA2 ));
    ClassA2 value = serializer.Deserialize(reader) as ClassA2 ;
    return value;
  }
}

Upvotes: 1

Views: 825

Answers (2)

RBT
RBT

Reputation: 25907

I changed the input XMl which is getting serialized a bit to make it a valid XML. Please see the below code which is deserializing only ID property of ClassA1 present in Details property. You will have to use following import using System.Xml.Linq; at the top of your code file.

private static void NestedMemberSerialization()
{

    var serializedXml = "<ClassA2><ID>1</ID><Details><ClassA1><ID>2</ID><Name>4</Name><Value>2</Value><Description>3</Description></ClassA1></Details><SomeValue>2</SomeValue></ClassA2>";

    XDocument doc = XDocument.Parse(serializedXml);

    var mySteps = (from s in doc.Descendants("ClassA2")
                   select new ClassA2
                   {
                       ID = decimal.Parse( s.Element("ID").Value),
                       SomeValue = int.Parse( s.Element("SomeValue").Value),
                       Details = new ClassA1 { ID = decimal.Parse(s.Element("Details").Descendants("ClassA1").Descendants("ID").ElementAt(0).Value) }
                   }).ToList();

}

Upvotes: 1

ProgrammingLlama
ProgrammingLlama

Reputation: 38767

To exclude elements, you can either define a "ShouldSerialize" method in the same class as the data:

public bool ShouldSerializeDescription()
{
    return false;
}

public decimal Description { get; set; }

or use the [XmlIgnore] attribute above the property:

[XmlIgnore]
public decimal Description { get; set; }

In most cases I'd recommend XmlIgnore.

Regarding locating a member to populate the field with, there is nothing built in to achieve this as far as I'm aware of. You will just have to loop through and locate the values manually. See this post for more information.

Upvotes: 2

Related Questions