Snurka Bill
Snurka Bill

Reputation: 983

C# serializer/deserializer with same functionality as XStream in java

I need to accomplish very simple task: serialize and deserialize object hierarchy.

I've tried XMLSerializer, DataContractSerializer, NetDataContractSerializer but nothing seems to work, there is always some problem.

XMLSerializer is bad because it requires all properties to be public. (Net)DataContractSerializer(s) are bad because it's always missing some metadata - but there are no metadata when user creates XML.

So how would you solve this task? Consider classes:

class A {
    private B instanceB;
    private int integerValue;

    ... getters/setters
}

class B {
    private List<C> cInstanceList;
    private string stringValue; 
    ... getters/setters
}

class C {
    ... some other properties
    ... getters/setters
}

and user input:

<A>
  <B>
    <cInstanceList>
      <C>
        <someproperties>val</someproperties>
      </C>
      <C>
        <someproperties>differentVal</someproperties>
      </C>
    </cInstanceList>
    <strigValue>lalala<stirngValue>
  </B>
  <integerValue>42</integerValue>
</A>

What DataContractors missing is metadata like "Type" or "Namespace" etc. XStream doesn't need that. I know the type of deserializing object, so I need to write function:

public T Deserialize<T>(string xml);

my wanted use case:

var myDeserializedObject = Deserialize<A>(inputString);

What am I doing wrong? Would you solve it differently?

Upvotes: 0

Views: 174

Answers (1)

Filip Cordas
Filip Cordas

Reputation: 2561

No serializer will fix typing mistakes ;). this worked for me using DataContractSerializer XML (text.xml)

<A>
  <B>
    <cInstanceList>
      <C>

      </C>
      <C>
      </C>
    </cInstanceList>
    <stringValue>lalala</stringValue>
  </B>
  <integerValue>42</integerValue>
</A>

Classes

[DataContract(Namespace="")]
    class A
    {
        [DataMember(Name = "B")]
        private B instanceB;
        [DataMember(Name = "integerValue")]
        private int integerValue;

        public A(B instanceB, int integerValue)
        {
            this.instanceB = instanceB;
            this.integerValue = integerValue;
        }
    }

    [DataContract(Namespace = "")]
    class B
    {
        [DataMember(Name = "cInstanceList")]
        private List<C> cInstanceList;

        [DataMember(Name = "stringValue")]
        private string stringValue;

        public B(List<C> cInstanceList, string stringValue)
        {
            this.cInstanceList = cInstanceList;
            this.stringValue = stringValue;
        }
    }

    [DataContract(Namespace = "")]
    class C
    {
    }

Read

var dcs = new DataContractSerializer(typeof(A));
using (Stream reader = File.OpenRead("text.xml"))
{
    var result = (A)dcs.ReadObject(reader);
}

If you write it will add the xmlns:i="http://www.w3.org/2001/XMLSchema-instance" but won't make a difference you could remove it if you really need to.

Upvotes: 1

Related Questions