Reputation: 703
I'm using DataContractSerializer
in C# to deserialize xml file into object, and everything was working fine :)
My issue started when I add a new property to my class and xml file. My new property name is EncryptionKey
every time I deserialize file, property value remain null
, but when i change the name of xml element and property to anEncryptionKey
it deserialized correctly without changing anything else in the code.
Actually I try a lot of options for property name like EncryptKey
, Encrypt
and a lot more but I ended up with anEncryptionKey
.
Maybe there is some constraint on properties names or something like that or I just need more caffeine to figure it out.
Xml file:
<?xml version="1.0" encoding="utf-8" ?>
<KioskSettings xmlns="http://schemas.datacontract.org/2004/07/Proxies" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<ID>20198</ID>
<HeartBeatInterval>1</HeartBeatInterval>
<ServerURL></ServerURL>
<EncryptionKey>abcd</EncryptionKey>
</KioskSettings>
Code i use to deserialize file into object:
private KioskSettings ReadEngineSettingsFromSimulatorXmlFile()
{
KioskSettings engineSettings = new KioskSettings();
DataContractSerializer serializer = new DataContractSerializer(typeof(KioskSettings));
FileStream fs = new FileStream(@"c:\simulation.xml", FileMode.Open);
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (serializer.IsStartObject(reader))
{
engineSettings = (KioskSettings)serializer.ReadObject(reader);
}
break;
}
}
fs.Flush(); fs.Close();
reader.Close();
reader = null;
serializer = null;
return engineSettings;
}
KioskSettings class:
public class KioskSettings
{
public string ID { get; set; }
public int HeartBeatInterval {get; set;}
public string ServerURL {get; set;}
public string EncryptionKey { get; set; }
}
Note: Above code may contains some syntax errors because I modify it to make it short.
Upvotes: 1
Views: 1062
Reputation: 5155
You need to ensure your XML nodes are in alphabetical order:
<?xml version="1.0" encoding="utf-8" ?>
<KioskSettings xmlns="http://schemas.datacontract.org/2004/07/Proxies" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<EncryptionKey>abcd</EncryptionKey>
<HeartBeatInterval>1</HeartBeatInterval>
<ID>20198</ID>
<ServerURL></ServerURL>
</KioskSettings>
Serialize a KioskSettings object with the following code, and ensure your XML takes the same form:
public static string DataContractSerializeObject<T>(T objectToSerialize)
{
using (MemoryStream memStm = new MemoryStream())
{
var serializer = new DataContractSerializer(typeof(T));
serializer.WriteObject(memStm, objectToSerialize);
memStm.Seek(0, SeekOrigin.Begin);
using (var streamReader = new StreamReader(memStm))
{
string result = streamReader.ReadToEnd();
return result;
}
}
}
If you need to preserve a specific order then specify the DataMember
attribute on your class properties - Data Member Order e.g.
[DataContract]
public class KioskSettings
{
[DataMember(Order = 1)]
public string ID { get; set; }
[DataMember(Order = 2)]
public int HeartBeatInterval { get; set; }
[DataMember(Order = 3)]
public string ServerURL { get; set; }
[DataMember(Order = 4)]
public string EncryptionKey { get; set; }
}
Upvotes: 2