0

I'm trying to use IXmlSerializable ReadXml and WriteXml methods with an XDocument object ( using the Foo.WriteTo( ... ) and XDocument.Load( ... ) methods.

I want to store the class which implements the IXmlSerializable interface into a variable stored within the default Application Settings class.

Trying to do this results in a pretty obnoxious failure :

enter image description here

This is the Settings class :

enter image description here

This is the class wrapping the

[Serializable]
class XmlModel : IXmlSerializable {
    public XDocument _foo = new XDocument(
        new XElement( "Foo",
            new XElement( "Bar", "Baz" ) ) );

    public XmlModel( XDocument Foo ) {
        _foo = Foo;
    }

    public XmlSchema GetSchema( ) {
        return null;
    }

    public void ReadXml( XmlReader reader ) {
        this._foo = XDocument.Load( reader );
    }

    public void WriteXml( XmlWriter writer ) {
        _foo.WriteTo( writer );
    }
}

Aaaand this is the Program class ( I'm using just a simple console application to reproduce the issue )

class Program {
    static void Main( string[ ] args ) {
        if ( Settings.Default.DoUpgrade ) {
            Settings.Default.Upgrade( );
            Settings.Default.DoUpgrade = false;
            Settings.Default.Save( );
        }
        Console.WriteLine( Settings.Default.Foo._foo );
        Console.ReadLine( );
    }
}

This exception pops up because I have all exceptions turned on, but even with them OFF, the ApplicationSettings file isn't taking the data.

Why is this happening?

Will
  • 3,413
  • 7
  • 50
  • 107
  • Do you have to store such complex data in Settings? Why not use self-defined config file instead? – Lei Yang Dec 13 '16 at 01:14
  • @LeiYang I'd rather keep the class within the application settings. It's how I've done it until now ( except for a change wherein the underlying data used to be stored separately but now is all stored in a single XDocument ). I don't know any better way to create an application config. – Will Dec 13 '16 at 01:30
  • You've always doing the wrong way then. – Lei Yang Dec 13 '16 at 01:33

1 Answers1

0

I found the answer, and Lei Yang was correct ( at least in the sense that I can't use XDocuments with Application Settings ).

According to the docs...

    /// <summary>
    /// Output this <see cref="XElement"/> to an <see cref="XmlWriter"/>.
    /// </summary>
    /// <param name="writer">
    /// The <see cref="XmlWriter"/> to output the XML to.
    /// </param>
    public void Save(XmlWriter writer) {
        if (writer == null) throw new ArgumentNullException("writer");
        writer.WriteStartDocument();
        WriteTo(writer);
        writer.WriteEndDocument();
    }

XDocument.Save( ) calls writer.WriteStartDocument( ), which is apparently called further up in the ApplicationSettings.Save( ) method, and since XDocument.Save( ... ) cannot be overridden, I ( and by extension, everyone else who tried this ) will have to find another way.

EDIT

Using an XElement instead of an XDocument allows it to be saved into an ApplicationSettings class :

[Serializable]
class XmlModel : IXmlSerializable {
    public XElement _foo = new XElement(
        "Foo", new XElement( "Bar", "Baz" ) );

    public XmlModel( XElement Foo ) {
        _foo = Foo;
    }

    public XmlSchema GetSchema( ) {
        return null;
    }

    public void ReadXml( XmlReader reader ) {
        this._foo = XElement.Load( reader );
    }

    public void WriteXml( XmlWriter writer ) {
        _foo.WriteTo( writer );
    }
}
Will
  • 3,413
  • 7
  • 50
  • 107