views:

242

answers:

2
+1  Q: 

IXmlSerializable

Could you guys help me I have a problem with deserialization via IXmlSerializable

var ArrayOfAccounts = new Accounts(); //This class structure I'm trying to read

Class Accounts:List<Session>{ }

Class Shedule{
  public DateTime StartAt { get; set; }
  public DateTime EndAt { get; set; }
}

Class Session:IXmlSerializable {
 public string Name{get;set;}
 public string Pass{get;set;}
 public List<Shedule> Shedules = new List<Shedule>();


 public void ReadXml(System.Xml.XmlReader reader){
    //AND HERE IS A PROBLEM. I don't know how to implement right code here. I've tried 
    //code below, but this one works for the first account only, and doesn't restore others 

  Schedules.Clear();
  XmlReader subR = reader.ReadSubtree();

  if (reader.MoveToAttribute("Name"))
      Name = reader.Value;
   if (reader.MoveToAttribute("Password"))
      Password = reader.Value;

 reader.MoveToContent();

 while (subR.ReadToFollowing("Schedule"))
        {
            XmlSerializer x = new XmlSerializer(typeof(Schedule));
            object o = x.Deserialize(subR);
            if (o is Schedule) Schedules.Add((Schedule)o);
        }
 }

And the xml itself looks like:

<Accounts>
   <Session UserName="18SRO" Password="shalom99">
     <Schedule>
      <StartAt>0001-01-01T09:30:00</StartAt>
      <EndAt>0001-01-01T16:00:00</EndAt>
    </Schedule>
  </Session>
</Accounts>
+1  A: 

Since you've defined the classes, you should just be able to use XML Serialization attributes, and use the default XML deserializer.

Your structure doesn't look overly complicated, is there any particular reason you're not using serialization attributes instead of manually deserializing?

micahtan
I want add some password decryption algorithm later. And I don't want to mess with inherited fields. That's why I decided to use IXmlSerializable... Actually my problem is in reading nested fields.. like <foo> <child name="A"> </child> <child name="B"> </child></foo>
Ike
That's easy to do as well -- just have two properties, one that is ignored by XML (your non-decrypted version), and the the serialized version (the decrypted version).
micahtan
dint't get it...I have a class inherited from the other. And I wish to ignore inherited members during serialization. how to do this?
Ike
My original comment was for handling the password/hashed-password case. As far as hiding inherited members, I don't think there's a good way to do that directly. I've used serialization proxy classes, but you may be better off writing your custom deserialization. One question I would ask, however, is why you want to remove the inherited fields? Since I could set the values in code, it would seem strange to me (as a consumer of your class) to not have those values show up in my serialized XML.
micahtan
+1  A: 

Re inherited fields... if you switch to DataContractSerializer, then fields are "opt in" rather than "opt out" - but you lose the ability to specify attributes (everything is an element). A trivial example:

[DataContract(Name="foo")]
public class Foo
{
    [DataMember(Name="bar")]
    public string Bar { get; set; }

    public int ThisIsntSerialized {get;set;}
}

However - adding unexpected subclasses is a pain for both XmlSerializer and DataContractSerializer. Both can do it, but it isn't pretty...

Marc Gravell