Notus Herve
Notus Herve

Reputation: 33

How to serialize container classes using custom serializer in C#

I need to serialize some container classes for which the HasValue property is evaluated to true.

I don´t need to remove invalid elements from the container List prior to the serialization. The serializer should be able to determine which objects need to be serialized or not. I guess a custom serializer can be suitable for my need but i don´t know how to figure out this. Any other solution / best practice would be appreciated.

Here my classes

public static class ContainerFactory
{
         public static Container Create()
         {
             var container = new Container();
             container.Persons.AddRange(new[]
                 {
                     new Person
                         {
                             FirstName = "Thomas"
                         },
                      new Person
                         {
                             FirstName = "Andrew",
                             LastName = "Martin",
                              Vehicles = new Vehicles
                                 {
                                    new Vehicle { Hsn = "65976GHR", Tsn = "HUZUKL"}
                                 }
                         },
                          new Person
                         {
                             FirstName = "Arnold",
                             LastName = "Beckmann",
                             Vehicles = new Vehicles
                                 {
                                    new Vehicle { Hsn = "345XXXHZ"},
                                    new Vehicle { Hsn = "659JUKI", Tsn = "787999HGF"}
                                 }
                         }

                 });
             return container;
         }
}

[Serializable]
public class Container
{
    public Container()
    {
        Persons = new Persons();
    }

    public Persons Persons { get; set; }

    public void Serialize()
    {
        var serializer = new XmlSerializer(typeof (Container));
        var streamWriter = new StreamWriter(@"C:\container.xml", false);
        serializer.Serialize(streamWriter, this);
    }
}

public class Persons: List<Person>
{
}

public class Vehicles: List<Vehicle>
{
    public Vehicles()
    {
    }

    public Vehicles(IEnumerable<Vehicle> vehicles):base(vehicles)
    {
    }
}

[Serializable]
public class Person : IHasValue
{
    public Person()
    {
        this.Vehicles = new Vehicles();
        this.Id = Guid.NewGuid().ToString();
    }

    public string Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Vehicles Vehicles { get; set; }

    public bool HasValue
    {
        get { return !string.IsNullOrEmpty(this.FirstName) && !string.IsNullOrEmpty(this.LastName); }
    }
}

public interface IHasValue
{
    bool HasValue { get;}
}

public class Vehicle: IHasValue
{
    public string Hsn { get; set; }
    public string Tsn { get; set; }

    public bool HasValue
    {
        get { return !string.IsNullOrEmpty(Hsn) && !string.IsNullOrEmpty(Tsn); }
    }
}

//Using the .NET XMLSerializer to test my container
Container container = ContainerFactory.Create();
container.Serialize();
Console.WriteLine("Press any Key to continue...");
Console.ReadLine(); 

Output

<?xml version="1.0" encoding="utf-8"?>
<Container xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Persons>
    <Person>
      <Id>76cdcc18-b256-40fe-b813-cd6c60e682ca</Id>
      <FirstName>Thomas</FirstName>
      <Vehicles />
    </Person>
    <Person>
      <Id>26623bf9-d799-44d2-bc1a-7ec91292d1cd</Id>
      <FirstName>Andrew</FirstName>
      <LastName>Martin</LastName>
      <Vehicles>
        <Vehicle>
          <Hsn>65976GHR</Hsn>
          <Tsn>HUZUKL</Tsn>
        </Vehicle>
      </Vehicles>
    </Person>
    <Person>
      <Id>f645cde1-10c8-4df5-81df-9b9db7712ec3</Id>
      <FirstName>Arnold</FirstName>
      <LastName>Beckmann</LastName>
      <Vehicles>
        <Vehicle>
          <Hsn>345XXXHZ</Hsn>
        </Vehicle>
        <Vehicle>
          <Hsn>659JUKI</Hsn>
          <Tsn>787999HGF</Tsn>
        </Vehicle>
      </Vehicles>
    </Person>
  </Persons>

How can I achieve my goal to serialize Vehicles/Persons only for which HasValue == true?

Upvotes: 0

Views: 1516

Answers (2)

draqool
draqool

Reputation: 11

Persons : List < Person > should be also Serializable.

public void GetObjectData( SerializationInfo info, StreamingContext context )    
{
    foreach (Person person in this)    
    {
        if(person.HasValue)
        {
            info.AddValue("Firsname", person, typeof(Person));

            info.AddValue (....);

            ..............

        }
    }
}

Upvotes: 1

No Idea For Name
No Idea For Name

Reputation: 11597

you need to use:

  1. ISerializable interface - every class that you want to serialize and every property you want in different node need to use the appropriate attribute. look at the example here
  2. when you serialize a class check if HasValue == true

Upvotes: 1

Related Questions