Reputation: 29
I have a problem with deserialize an XML string into C# objects. The problem is that I the result will always be null. This is my XML string which is stored into a string variable.
<objects>
<object>
<dateadded>1614924419</dateadded>
<id>CF7E7B22-1D3A-4CFE-91F9-F8C5C2DB4069</id>
<name>NorthernLights</name>
<parentid>ED98C97F-A202-48ED-AEEA-34362508A30B</parentid>
<type>file</type>
</object>
<object>
<dateadded>1614924419</dateadded>
<id>CF7E7B22-1D3A-4CFE-91F9-F8C5C2DB4070</id>
<name>Northern</name>
<parentid>ED98C97F-A202-48ED-AEEA-34362508A30C</parentid>
<type>file</type>
</object>
</objects>
Those are the classes that I have created that represent the XML document. I suppose something is wrong there. Can someone help me with this?
This is the class for the objects
tag:
namespace DataContractSample.DataContract.Model
{
using System.Collections.Generic;
using System.Runtime.Serialization;
[DataContract(Name = "objects", Namespace = "", IsReference = false)]
[KnownType(typeof(IList<Image>))]
public class Images
{
[DataMember(Name = "object", EmitDefaultValue = false, IsRequired = true)]
public IList<Image> ImageList;
}
}
This is the class for the object
tag:
namespace DataContractSample.DataContract.Model
{
using System;
using System.Runtime.Serialization;
[DataContract(Name = "object", Namespace = "")]
public class Image
{
[DataMember(Name = "Id")]
public Guid id { get; set; }
[DataMember(Name="parentid")]
public Guid ParentId { get; set; }
[DataMember(Name="name")]
public string Name { get; set; }
[DataMember(Name = "type")]
public string Type { get; set; }
[DataMember(Name = "dateadded")]
public string DateAdded { get; set; }
}
}
Thanks!
Upvotes: 0
Views: 241
Reputation: 22839
The problem with your approach is that you want to deserialize the <objects>
into a class and into a property at the same time. This won't work. Here, I present two different ways how you can solve this problem.
If you have an outer node around <objects>
:
<?xml version="1.0" encoding="utf-8" ?>
<top>
<objects>
<object>
<dateadded>1614924419</dateadded>
<id>CF7E7B22-1D3A-4CFE-91F9-F8C5C2DB4069</id>
<name>NorthernLights</name>
<parentid>ED98C97F-A202-48ED-AEEA-34362508A30B</parentid>
<type>file</type>
</object>
<object>
<dateadded>1614924419</dateadded>
<id>CF7E7B22-1D3A-4CFE-91F9-F8C5C2DB4070</id>
<name>Northern</name>
<parentid>ED98C97F-A202-48ED-AEEA-34362508A30C</parentid>
<type>file</type>
</object>
</objects>
</top>
with this modified top level entity:
[DataContract(Name = "top", Namespace = "", IsReference = false)]
public class Images
{
[DataMember(Name = "objects", EmitDefaultValue = false, IsRequired = true)]
public List<Image> ImageList;
}
then deserialization works like a charm:
using var file = File.OpenRead("sample.xml");
using var reader = new XmlTextReader(file);
var serializer = new DataContractSerializer(typeof(Images));
var data = (Images)serializer.ReadObject(reader);
Console.WriteLine(data.ImageList.Count); // Will print 2
If you don't have an outer node around <objects>
then you can use CollectionDataContract
:
[CollectionDataContract(Name = "objects", Namespace = "")]
public class Images: List<Image>
{
}
and it will work as well:
using var file = File.OpenRead("sample.xml");
using var reader = new XmlTextReader(file);
var serializer = new DataContractSerializer(typeof(Images));
var data = (Images)serializer.ReadObject(reader);
Console.WriteLine(data.Count); // Will print 2
Upvotes: 1