It depends. XmlSerializer has severe limitations such as the requirement that the target class has a parameterless constructor, and only public read/write properties and fields can be serialized.
However, on the plus side, XmlSerializer has good support for customising the XML document that is produced or consumed. XmlSerializer’s features mean that it is most suitable for cross-platform work, or for constructing objects from existing XML documents.
SoapFormatter and BinaryFormatter have fewer limitations than XmlSerializer. They can serialize private fields, for example. However they both require that the target class be marked with the [Serializable] attribute, so like XmlSerializer the class needs to be written with serialization in mind.
Also there are some quirks to watch out for – for example on deserialization the constructor of the new object is not invoked.
The choice between SoapFormatter and BinaryFormatter depends on the application. BinaryFormatter makes sense where both serialization and deserialization will be performed on the .NET platform and where performance is important. SoapFormatter generally makes more sense in all other cases, for ease of debugging if nothing else.
customise the serialization process
XmlSerializer supports a range of attributes that can be used to configure serialization for a particular class. For example, a field or property can be marked with the [XmlIgnore] attribute to exclude it from serialization.
Another example is the [XmlElement] attribute, which can be used to specify the XML element name to be used for a particular property or field.
Serialization via SoapFormatter/BinaryFormatter can also be controlled to some extent by attributes. For example, the [NonSerialized] attribute is the equivalent of XmlSerializer’s [XmlIgnore] attribute.
Ultimate control of the serialization process can be acheived by implementing the the ISerializable interface on the class whose instances are to be serialized.