• 10
• 9
• 12
• 14
• 14

C# problem with Xml Serialization

This topic is 3481 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hi, I'm working on a project that requires storing and restoring settings from an Xml file. Unfortunately it seems .NET's XmlSerializer only likes fully public members, because everytime I use private, protected or internal, either it doesn't write the value at all, or I get a CS0272 error. I also tried readonly, it worked, but wrote a bunch of garbage to the file along with the value. Does anyone know a way to keep the setters for members private and still use Xml serialization? I've searched google and someone suggested using InternalsVisibleTo on System.Xml, but I haven't gotten that to work either. Please help, I don't want to have to reinvent the wheel. Here's the code:
namespace Bob
{

public abstract class TextSerializer<T>
{

[XmlIgnore]
private readonly XmlSerializer XmlSerializer = new XmlSerializer( typeof( T ) );

public void Serialize( IO.Stream stream )
{
XmlSerializer.Serialize( stream, this );
return;
}

public T Deserialize( IO.Stream stream )
{
return (T)XmlSerializer.Deserialize( stream );
}

}

[XmlRoot("SerialPort")]
public class SerialPort : TextSerializer<SerialPort>
{

[XmlElement("BaudRate")]
public int BaudRate { get; set; } // private set does not work

[XmlElement("Name")]
public string Name { get; set; }

public SerialPort()
{
return;
}

public SerialPort( string name, int baudRate )
{
Name = name;
BaudRate = baudRate;
return;
}

}

}



Share on other sites
Xml.Serializer only serialises/deserialises public members and properties by design. I don't think there's a way to override this behaviour - the various XmlAttributes only work on public members and properties. You may just have to change your design a bit so that you can work with just public members.

Share on other sites
Yes I could just use public members, but I don't want to. I consider it bad practive and I'm pretty sure MS does as well. I don't understand why it acts this way, the binary serializer works with non-public data, why can't the XML one?

Share on other sites
Quote:
 Original post by ScetYes I could just use public members, but I don't want to. I consider it bad practive and I'm pretty sure MS does as well. I don't understand why it acts this way, the binary serializer works with non-public data, why can't the XML one?

Because the XML complement of the Binary serializer is the SOAP Serializer, not the XML Serializer.

Share on other sites
Quote:
 Original post by ScetI don't understand why it acts this way, the binary serializer works with non-public data, why can't the XML one?

The binary and XML serializers are completely different classes. They don't even implement the same interface. Technically, the BinaryFormatter is a formatter class, designed to completely serialize or deserialize an entire object graph.

On the other hand the XmlSerializer class is for the purpose of serializing or deserializing public properties and fields only. Certain types of collections such as List<T> are not supported by this class.

You might want to look into the DataContractAttribute class. It can use private fields. It has an example of using it along with the XmlDictionaryWriter and XmlDictionaryReader classes to serialize and deserialze an object to/from XML. Note you will need .Net 3.0 or higher to use these classes.

Share on other sites
Quote:
 Original post by ScetYes I could just use public members, but I don't want to. I consider it bad practive and I'm pretty sure MS does as well. I don't understand why it acts this way, the binary serializer works with non-public data, why can't the XML one?

I usually have classes that serves no purpose except storing, serializing and deserializing data that sit within another class that actually uses the data and keeps it from being edited incorrectly.

Share on other sites
Quote:
Original post by cyansoft
Quote:
 Original post by ScetI don't understand why it acts this way, the binary serializer works with non-public data, why can't the XML one?

The binary and XML serializers are completely different classes. They don't even implement the same interface. Technically, the BinaryFormatter is a formatter class, designed to completely serialize or deserialize an entire object graph.

On the other hand the XmlSerializer class is for the purpose of serializing or deserializing public properties and fields only. Certain types of collections such as List<T> are not supported by this class.

You might want to look into the DataContractAttribute class. It can use private fields. It has an example of using it along with the XmlDictionaryWriter and XmlDictionaryReader classes to serialize and deserialze an object to/from XML. Note you will need .Net 3.0 or higher to use these classes.

The Xml Serializer can serialize lists.

Share on other sites
Quote:
 Original post by mpipeThe Xml Serializer can serialize lists.

According to Microsoft, it can't:

Quote:
 Serialization of ArrayList and Generic ListThe XmlSerializer cannot serialize or deserialize the following:Arrays of ArrayListArrays of List(T)

Quote:
 Original post by ernowhttp://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable.aspxThis way you can serialize anything you'd like.

Serialize anything you'd like in XML only. If you need to support other formats, you need to use the classes in the System.Runtime.Serialization namespace. If you only need XML, use the IXmlSerializable interface as suggested by ernow as it it's much easier to use than the more flexible alternatives.

Share on other sites
Quote:
Original post by cyansoft
Quote:
 Original post by mpipeThe Xml Serializer can serialize lists.

According to Microsoft, it can't:

Quote:
 Serialization of ArrayList and Generic ListThe XmlSerializer cannot serialize or deserialize the following:Arrays of ArrayListArrays of List(T)

It can't serialize arrays of lists, but it can most certainly serialize individual lists. I know this for a fact to be true, since I'm using XmlSerializer to serialize List<string> at work, among other things. However I also know for a fact that it can't serialize dictionaries or hashtables, which I'm still a little peeved about (but managed to get around by using a special accessor).