IamaC
IamaC

Reputation: 377

Deserialize using DataContractSerializer

I am trying to Deserialize an xml file that looks like the following

<?xml version="1.0"?>
<Test xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication6">
  <values>
    <String>Value 1</String>
    <String>Value 2</String>
  </values>
</Test>

to an object that is this

[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/ConsoleApplication6")]
public class Test
{
    [DataMember(Name = "values")]
    public String[] values;
}

with

var ds = new DataContractSerializer(typeof(Test));
        using (Stream stream1 = File.OpenRead(@"C:\Projects\test1.xml"))
        {

            Test rr = (Test)ds.ReadObject(stream1);
        }

However none of the values are deserializing. I just see and empty array in Test rr. Could you please tell what I am doing wrong. Thanks in advance.

Upvotes: 1

Views: 694

Answers (2)

Mike Hixson
Mike Hixson

Reputation: 5189

If you need fine control of the XML that is emitted when serializing, you should not use DataContractSerializer. It is has very limited flexibility. You would be better off using XmlSerializer, which has liimtitations as well, but is much more flexible than DataContractSerializer.

That being said, here is how you can do what you want with DataContractSerializer.

Change the default namespace on your xml to use the one that DataContractSerializeruses by default.

<?xml version="1.0"?>
<Test xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/">
  <values>
    <String>Value 1</String>
    <String>Value 2</String>
  </values>
</Test>

Instead of using string[] create your own custom type that derives from List<string>. This must be done solely for the purpose of having something to hang CollectionDataContractAttribute on. CollectionDataContractAttribute is what will let you specify the name of the elements inside <values>.

[DataContract]
public class Test
{
    [DataMember(Name = "values")]
    public TestValues values;

}

[CollectionDataContract(ItemName = "String")]
public class TestValues : List<string> { }

Upvotes: 1

Richard Schneider
Richard Schneider

Reputation: 35477

The DataContractSerializer has its own rules for XML and cannot support all XML forms. I suggest using the XmlSerializer.

Use this definition

[XmlClass(Namespace = "http://schemas.datacontract.org/2004/07/ConsoleApplication6")]
public class Test
{
    [XmlArray("values")]
    [XmlArrayItem("String")]
    public String[] values;
}

Upvotes: 1

Related Questions