1

I am facing issue in serialization of XmlDocument when XmlSerializer is instantiated with XmlRootAttribute. This is the sample that I have prepared to reproduce the issue.

class Program
    {
        static void Main(string[] args)
        {
            SerializeDataSet("a1.xml");
        }

        private static void SerializeDataSet(string filename)
        {
            XmlDocument testProperties = new XmlDocument();
            XmlSerializer ser = new XmlSerializer(typeof(XmlDocument), null, new Type[0], new XmlRootAttribute("dummy"), "testns");

            // Creates a DataSet; adds a table, column, and ten rows.
            DataSet ds = new DataSet("mydatads");
            DataTable t = new DataTable("mytable1");
            DataColumn c = new DataColumn("mycolumn");
            t.Columns.Add(c);
            ds.Tables.Add(t);
            DataRow r;
            for (int i = 0; i < 10; i++)
            {
                r = t.NewRow();
                r[0] = "row " + i;
                t.Rows.Add(r);
            }
            testProperties.LoadXml(ds.GetXml());
            TextWriter writer = new StreamWriter(filename);
            ser.Serialize(writer, testProperties);
            writer.Close();
        }
    }

This is failing with following exception.

 Unhandled exception. System.InvalidOperationException: There was an error generating the XML document.
 ---> System.InvalidOperationException: This element was named 'mydatads' from namespace '' but should have been named 'dummy' from namespace ''.
   at System.Xml.Serialization.XmlSerializationWriter.WriteElement(XmlNode node, String name, String ns, Boolean isNullable, Boolean any)
   at System.Xml.Serialization.XmlSerializationWriter.WriteElementLiteral(XmlNode node, String name, String ns, Boolean isNullable, Boolean any)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterXmlDocument.Write1_dummy(Object o)
   --- End of inner exception stack trace ---
   at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
   at System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o, XmlSerializerNamespaces namespaces)
   at System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o)
   at Program.SerializeDataSet(String filename) in Program.cs:line 49
   at Program.Main(String[] args) in Program.cs:line 26

When I create instance of XmlSerializer as new XmlSerializer(typeof(XmlDocument)); then it works but then it misses the root element. Other than that, I don't have control over it. I can change XmlDocument but can't change XmlSerializer. I am not sure what is going wrong when XmlRootAttribute is present.

RockAndRoll
  • 2,247
  • 2
  • 16
  • 35
  • Xml Serialization requires classes. You do not have any classes. – jdweng Apr 23 '20 at 09:31
  • Its not necessary. I am trying to serialize XmlDocument which is serializable. At last I have added that If i remove that XmlRootAttribute part, then it works properly. – RockAndRoll Apr 23 '20 at 09:36
  • Why are you serializing the `XmlDocument` with an `XmlSerializer` when you can just save it directly to XML using [`XmlDocument.Save()`](https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmldocument.save)? For some examples see e.g. [What is the simplest way to get indented XML with line breaks from XmlDocument?](https://stackoverflow.com/q/203528/3744182) or [XMLDocument to xml file](https://stackoverflow.com/q/18204957/3744182). Serialization is designed to convert a c# object to XML via reflection but an `XmlDocument` is already an in-memory XML DOM so serialization is not required. – dbc Apr 23 '20 at 13:54
  • You have a conflict. The root folder should be same name as dataset name. – jdweng Apr 23 '20 at 14:45
  • @jdweng I tried that. Even if i keep them same, still it fails with "This element was named 'mydatads' from namespace '' but should have been named 'mydatads' from namespace .''." – RockAndRoll Apr 23 '20 at 16:34
  • When it works what is the root tag in the XML? Is it the same as the dataset? Are there any namespaces in xml? – jdweng Apr 23 '20 at 16:40
  • @jdweng yes in that case "mydatads" is root tag. but I don't have control over serialization code and I can't change it. For simplicity, there is no namespaces in xml. – RockAndRoll Apr 23 '20 at 16:44
  • Does it **have** to return `XmlDocument`? Could it return some other root object that contains arbitrary XML elements and attributes? – dbc Apr 23 '20 at 16:52
  • @dbc yes it has to return XmlDocument only. Can't change that. If I change, web service clients will break. – RockAndRoll Apr 23 '20 at 16:53
  • So, your constraints are that you **must** use `XmlDocument` and you **must** be able to serialize it with an `XmlSerializer` constructed with an `XmlRootAttribute`override? ... Actually could you return `XElement` or `XDocument` instead of `XmlDocument`? Clients would never know the difference would they? (Don't know if either would solve your problem.) – dbc Apr 23 '20 at 17:00
  • @dbc If I use XElement or XDocument, then client stub generated earlier might break which expects XmlDocument. – RockAndRoll Apr 23 '20 at 17:10
  • You might check that, the generated client usually depends on the XSD not the actual c# type. Actually, what technology are you using to generate clients? [tag:wcf]? Something else? – dbc Apr 23 '20 at 17:16
  • @dbc sure I will check that. Appreciate your responses. yes wcf only. – RockAndRoll Apr 23 '20 at 17:17
  • 1
    I tried replacing `XmlDocument` with `XElement`. There's no longer an exception, but the root element was not renamed, so that's not good enough. Then I tried creating a wrapper class with `[XmlAnyElement]` and `[XmlAnyElement]` element collections, and assigning the children of the `XmlDocument` to them -- and it worked. See: https://dotnetfiddle.net/0mv60i. You'll need to check whether the XSD generated for such a return is identical though. – dbc Apr 23 '20 at 18:14
  • Thanks @dbc. XSD is a bit different but yeah I got the idea. Appreciate it. – RockAndRoll Apr 24 '20 at 05:49

0 Answers0