Reputation: 22436
The property FilePattern
does not get deserialized from the xml:
<Parser FilePattern='*'/>
[Serializable(), XmlRoot("Parser")]
public class Parser : List<System.DateTime>
{
private string _FilePattern;
[XmlAttribute()]
public string FilePattern {
get { return _FilePattern; }
set { _FilePattern = value; }
}
}
private void ParserTest()
{
Parser Parser = Serialization.Deserialize("<Parser FilePattern='*'/>", typeof(Parser));
// Here, Parser.FilePattern is null
}
Parser
is just a class. How can I make it populate the FilePattern
property?
Upvotes: 1
Views: 381
Reputation: 22436
Sometimes you just want to do what you just want to do; the Framework be damned.
Here's a first draft of a routine that worked for me in my situation. As it evolves over time I will update my answer.
I have located this in my Serialization
helper module alongside my other Deserialize
methods for "normal" classes.
Basically, what it does is a normal deserialization, to let the xml deserializer to all the heavy lifting, then it populates the newly deserialized object with the properties of the xml element.
Like I say, it's a draft, but Marc Gravell said it was a lot of work, so I just had to do it (to make it not a lot of work for you)!
/// <summary>
/// Overcome limitation of xml serializer
/// that it can't deserialize properties of classes
/// that inherit from IEnumerable
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Xml"></param>
/// <returns></returns>
/// <remarks></remarks>
public T Deserialize<T>(string Xml) where T : IEnumerable
{
T functionReturnValue = default(T);
//let the xml serializer do the rest of the work
functionReturnValue = Deserialize(Xml, typeof(T));
//copy over the additional properties
using (XmlReader XmlReader = XmlTextReader.Create(new StringReader(Xml), new XmlReaderSettings {ValidationType = ValidationType.None,XmlResolver = null})) {
XmlReader.MoveToContent();
for (int Index = 0; Index <= XmlReader.AttributeCount - 1; Index++) {
XmlReader.MoveToAttribute(Index);
typeof(T).GetProperty(XmlReader.LocalName).SetValue(Deserialize(), XmlReader.Value, null);
}
}
return functionReturnValue;
}
public object Deserialize(string Xml, Type Type)
{
object functionReturnValue = null;
functionReturnValue = null;
if (Xml == string.Empty) {
return null;
}
_Serializer = new XmlSerializer(Type);
StringReader StringReader = new StringReader(Xml);
functionReturnValue = Serializer.Deserialize(StringReader);
if (functionReturnValue is IDeserializationEvents) {
((IDeserializationEvents)functionReturnValue).DeserializationComplete();
}
return functionReturnValue;
}
Upvotes: 1
Reputation: 4192
The XmlSerializer has special behavior when it comes to IEnumerable types, and so you may be witnessing some kind of conflict with that. You could consider doing something like the following that mimics the behavior you want without actually making your type a list:
[XmlRoot("Parser")]
public class Parser
{
public Parser()
{
this.Values = new List<DateTime>();
}
[XmlAttribute]
public string Attrib { get; set; }
[XmlElement("dateTime")]
public List<DateTime> Values { get; private set; }
}
Upvotes: 2