If I deserialize XML which include a comment-element and it is deserialize to a class with ordered properties I get the exception:
There is an error in XML document (4, 25). Unable to cast object of type 'System.Xml.XmlElement' to type 'System.Xml.XmlComment'.
This is the XML:
<?xml version="1.0" encoding="utf-8"?>
<ROOT>
<!--Hello World-->
<Field1>Hello1</Field1>
</ROOT>
Why does the XmlSerializer try to parse the <Field1>
element as a XmlComment when the field in the class is marked with the attribute '[XmlElement]'?
(this only happens when using ordered elements!).
The C# class:
public class oFoo1
{
[XmlAnyElement("Foo_Comment", Order = 0)]
public XmlComment? FooComment { get; set; }
[XmlElement(Order = 1)]
public string? Field1;
public oFoo1() {}
}
Code to instantiate object and serialization:
public static void Main()
{
// Instantiate object
var CFG = new oFoo1()
{
FooComment = new XmlDocument().CreateComment("Hello World"),
Field1 = "Hello1",
};
// Serialize object
Serialize_to_File<oFoo1>(Obj: CFG, Path: @"c:\temp\test.xml");
// Deserialize object (will print exception)
var Obj = Serialize_to_Object<oFoo1>(Path: @"c:\temp\test.xml");
}
public static void Serialize_to_File<T>(T Obj, string Path)
{
XmlSerializerNamespaces NS = new XmlSerializerNamespaces();
NS.Add(prefix:"", ns: "");
XmlWriterSettings XWS = new XmlWriterSettings() {Indent = true, IndentChars = "\t"};
using (XmlWriter XW = XmlWriter.Create(outputFileName: Path, settings: XWS))
{
XmlSerializer X = new XmlSerializer(typeof(T), root: new XmlRootAttribute("ROOT"));
X.Serialize(xmlWriter: XW, o: Obj, namespaces: NS);
}
}
public static object? Serialize_to_Object<T>(string Path)
{
try
{
T? Obj;
using (XmlReader XR = XmlReader.Create(inputUri: Path))
{
var XS = new XmlSerializer(typeof(T), new XmlRootAttribute("ROOT"));
Obj = (T?)XS.Deserialize(XR);
}
return Obj;
}
catch (Exception Ex)
{
Console.WriteLine(
Ex.Message + "\n" +
(Ex.InnerException ?? new Exception()).Message
);
return null;
}
}
UPDATE: Even though the question and problem (bug) stands, and that's why I don't delete it, the purpose is not after some thoughts. The purpose was to create a "template" of an application config-file with build-in documentation and ordering of comments and properties is advantageous. But user might change the order of the properties in the config-file themselves (which is expected to be OK in a xml file) and that will break deserialization anyway, so ordered elements isn't feasible after all. To archive my goal I guess I have to create a copy of the config-class with order-attributes and serialize that when creating the template-config-file, and then use the "real" config-class for deserialization.