Using .Net what limitations (if any) are there in using the XmlSerializer? For example, can you serialize Images to XML?
Serialization/ De-serialization allow communication with another application by sending and receiving data. With XmlSerializer, you can control how objects are encoded into XML. Call the Serialize method with the parameters of the StreamWriter and object to serialize.
Since XmlSerializer is one of the few thread safe classes in the framework you really only need a single instance of each serializer even in a multithreaded application.
The XmlSerializer creates C# (. cs) files and compiles them into . dll files in the directory named by the TEMP environment variable; serialization occurs with those DLLs. These serialization assemblies can be generated in advance and signed by using the SGen.exe tool.
Yes, you can tell the XmlSerializer to ignore namespaces during de-serialization. Note this is the kind of thing I meant. You are not telling the XmlSerializer to ignore namespaces - you are giving it XML that has no namespaces.
I generally find the XmlSerializer to be a poor choice for any POCO that's more than just a DTO. If you require specific XML, you can go the Xml*Attribute and/or IXmlSerializable route - but you're left with an object pretty mangled.
For some purposes, it still an obvious choice - even with it's limitations. But, for simply storing and reloading data, I've found BinaryFormatter to be a much easier choice with less pitfalls.
Here's a list of some annoyances with XmlSerializer - most I've been bitten by at one point or another, others I found over at MSDN:
The XmlSerializer gives special treatment to classes that implement IEnumerable or ICollection. A class that implements IEnumerable must implement a public Add method that takes a single parameter. The Add method's parameter must be of the same type as is returned from the Current property on the value returned from GetEnumerator, or one of that type's bases.
A class that implements ICollection (such as CollectionBase) in addition to IEnumerable must have a public Item indexed property (indexer in C#) that takes an integer, and it must have a public Count property of type integer. The parameter to the Add method must be the same type as is returned from the Item property, or one of that type's bases. For classes that implement ICollection, values to be serialized are retrieved from the indexed Item property, not by calling GetEnumerator.
To increase performance, the XML serialization infrastructure dynamically generates assemblies to serialize and deserialize specified types. The infrastructure finds and reuses those assemblies. This behavior occurs only when using the following constructors:
XmlSerializer.XmlSerializer(Type) XmlSerializer.XmlSerializer(Type, String)
If you use any of the other constructors, multiple versions of the same assembly are generated and never unloaded, which results in a memory leak and poor performance.
The XmlSerializer cannot be instantiated to serialize an enumeration if the following conditions are true: The enumeration is of type unsigned long (ulong in C#) and the enumeration contains any member with a value larger than 9,223,372,036,854,775,807.
The XmlSerializer class no longer serializes objects that are marked as [Obsolete].
You must have permission to write to the temporary directory (as defined by the TEMP environment variable) to deserialize an object.
The XmlSerializer has a few drawbacks.
I (stupidly) wrote my own serializer to get around some of these problems. Don't do that; it is a lot of work and you will find subtle bugs in it months down the road. The only thing I gained in writing my own serializer and formatter was a greater appreciation of the minutia involved in object graph serialization.
I found the NetDataContractSerializer when WCF came out. It does all the stuff from above that XmlSerializer doesn't do. It drives the serialization in a similar fashion to the XmlSerializer. One decorates various properties or fields with attributes to inform the serializer what to serialize. I replaced the custom serializer I had written with the NetDataContractSerializer and was very happy with the results. I would highly recommend it.
Another problem is that calling the constructor of XmlSerializer will compile code at runtime and will generate a temp DLL (in the %temp% folder) with the code to do the de/serialization.
You can watch the code if you add the following lines to app.config:
<system.diagnostics>
<switches>
<add name="XmlSerialization.Compilation" value="4"/>
</switches>
</system.diagnostics>
This takes a lot of time the first time you serialize a class and needs code with permissions for compiling and writing to disk.
A way to get around that is to precompile these DLL using the sGen.exe tool that comes with VS 2005+.
Look here for more information.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With