Update: I was wrong, and private setters do not appear to work (strange, I’m sure I verified this in my test code, but it didn’t work in practice). See below.
It’s been ages since I used XmlSerializer, or even written meaningful amounts of code in C# for that matter, which is why I was utterly stumped by this problem. Try running this code:
[XmlRoot( "test" )] public class Test { private readonly string _string1; private readonly string _string2; public Test( string string1, string string2 ) { _string1 = string1; _string2 = string2; } [XmlAttribute( "attr" )] public string String1 { get { return _string1; } } [XmlElement( "element" )] public string String2 { get { return _string2; } } } /// ... XmlSerializer xs = new XmlSerializer( typeof( Test ), "" ); XmlSerializerNamespaces xsn = new XmlSerializerNamespaces(); xsn.Add("", ""); // Gets rid of redundant xmlns: attributes StringWriter pw = new StringWriter(); xs.Serialize( pw, new Test( "1", "2" ), xsn ); Console.WriteLine( pw.GetStringBuilder().ToString() );
<?xml version="1.0" encoding="utf-16"?> <test />
The solution? Add a setter to each of your serializable properties. Don’t need a setter because the class is immutable? Mark it as private and you’re good to go. Tough – you’re going to need one anyway, private/internal/protected setters don’t appear to work. If you must use XmlSerializer you should throw a NotImplementedException from these setters, but in my opinion the resulting contract clutter implies you should simply avoid XmlSerializer altogether.
Although this behavior makes sense in light of how XmlSerializer can be used for both serialization and de-serialization, what threw me off was that no exception is thrown – the contract doesn’t require a setter property, and the serializer output is corrupt. Beware!
Remember Me
a@href@title, b, blockquote@cite, em, i, strike, strong, sub, super, u