1)
Well, if you look into the inner exception you see that the namespace of the xml is not known
2) To get along, I would first build a valid object, then serialize it and see how the valid serialized structure looks like. A base class that does the serialization and deserialization might help you with this.
2.a)
public abstract class PersistentSettingsBase<T>
{
public string XMLSerialize()
{
XmlSerializer serializer = new XmlSerializer(this.GetType());
using (StringWriter myStream = new StringWriter())
{
serializer.Serialize(myStream, this);
myStream.Flush();
return (myStream.ToString());
}
}
public static T XMLDeserialize(string xmlString)
{
if (string.IsNullOrEmpty(xmlString))
{
throw new ArgumentNullException("xmlString");
}
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (StringReader myStream = new StringReader(xmlString))
{
try
{
return (T)serializer.Deserialize(myStream);
}
catch (Exception ex)
{
throw new InvalidOperationException("Failed to create object from xml string", ex);
}
}
}
}
2.b)
[Serializable()]
[XmlRoot("catalog")]
public class Calalog : PersistentSettingsBase<Calalog>
{
btw. "calalog" is a typo or what?
2.c)
void Main()
{
Calalog cars = null;
cars = new Calalog();
cars.createdDate = DateTime.Now;
var b1 = new Book();
b1.BookId = "bk101";
b1.Title = "COM and .NET Component Services";
b1.Isbn = "0-596-00103-7";
b1.Genre = Genre.Computer;
var b2 = new Book();
b2.BookId = "bk109";
b2.Title = "Paradox Lost";
b2.Isbn = "not set";
b2.Author = "Kress, Peter";
b2.Genre = Genre.ScienceFiction;
cars.Books = new[] { b1, b2 };
string serializedCatalog = cars.XMLSerialize();
Calalog deserializedCatalog = Calalog.XMLDeserialize(serializedCatalog);
string path = @"C:\temp\books.xml";
XmlSerializer serializer = new XmlSerializer(typeof(Calalog));
StreamReader reader = new StreamReader(path);
cars = (Calalog)serializer.Deserialize(reader);
Console.WriteLine(cars.Books.GetType());
reader.Close();
Console.ReadLine();
}
Now you have a working XML representation and can compare it to yours that is not yet working. You will see that you encoded Genre as an XMLElement in the file, however as an XmlAttribute in your code (there are other differences as well).
2.d, update:)
If you are not free to change the structure of the given xml-file you need to
change the definition of you Catalog class
[Serializable()]
[XmlRoot(ElementName = "catalog", Namespace = "http://library.by/catalog")]
public class Catalog : PersistentSettingsBase<Catalog>
{
[XmlAttribute]
public DateTime date;
[XmlElement("book")]
public Book[] Books { get; set; }
}
The DateTime in the XML-File has an attribute Name of "date" not "createdDate", the Namespace parameter in the root attribute avoids the error you get when reading this part.
You still will get an error with "Science Fiction" because your code makes no effort to use the Description attribute for conversion. I don't know how to handle this.