Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET XML serialization gotchas? [closed]

People also ask

Why is serialization not good?

It is not future-proof for small changes If you mark your classes as [Serializable] , then all the private data not marked as [NonSerialized] will get dumped. You have no control over the format of this data. If you change the name of a private variable, then your code will break.

What is the correct way of using XML serialization?

XML Serialization Considerations Type identity and assembly information are not included. Only public properties and fields can be serialized. Properties must have public accessors (get and set methods). If you must serialize non-public data, use the DataContractSerializer class rather than XML serialization.

What occasions the XML serialization throws an exception?

XmlSerializer throws exception when the type belongs to an assembly with no location property set #24614.

What is the serialization in .NET how is it affecting to .NET programming?

Serialization is a process of converting an object into a stream of data so that it can be is easily transmittable over the network or can be continued in a persistent storage location. This storage location can be a physical file, database or ASP.NET Cache.


Another huge gotcha: when outputting XML through a web page (ASP.NET), you don't want to include the Unicode Byte-Order Mark. Of course, the ways to use or not use the BOM are almost the same:

BAD (includes BOM):

XmlTextWriter wr = new XmlTextWriter(stream, new System.Text.Encoding.UTF8);

GOOD:

XmlTextWriter  wr = new XmlTextWriter(stream, new System.Text.UTF8Encoding(false))

You can explicitly pass false to indicate you don't want the BOM. Notice the clear, obvious difference between Encoding.UTF8 and UTF8Encoding.

The three extra BOM Bytes at the beginning are (0xEFBBBF) or (239 187 191).

Reference: http://chrislaco.com/blog/troubleshooting-common-problems-with-the-xmlserializer/


I can't make comments yet, so I will comment on Dr8k's post and make another observation. Private variables that are exposed as public getter/setter properties, and do get serialized/deserialized as such through those properties. We did it at my old job al the time.

One thing to note though is that if you have any logic in those properties, the logic is run, so sometimes, the order of serialization actually matters. The members are implicitly ordered by how they are ordered in the code, but there are no guarantees, especially when you are inheriting another object. Explicitly ordering them is a pain in the rear.

I've been burnt by this in the past.


When serializing into an XML string from a memory stream, be sure to use MemoryStream#ToArray() instead of MemoryStream#GetBuffer() or you will end up with junk characters that won't deserialize properly (because of the extra buffer allocated).

http://msdn.microsoft.com/en-us/library/system.io.memorystream.getbuffer(VS.80).aspx


If the serializer encounters a member/property that has an interface as its type, it won't serialize. For example, the following won't serialize to XML:

public class ValuePair
{
    public ICompareable Value1 { get; set; }
    public ICompareable Value2 { get; set; }
}

Though this will serialize:

public class ValuePair
{
    public object Value1 { get; set; }
    public object Value2 { get; set; }
}

IEnumerables<T> that are generated via yield returns are not serializable. This is because the compiler generates a separate class to implement yield return and that class is not marked as serializable.


You can't serialize read-only properties. You must have a getter and a setter, even if you never intend to use deserialization to turn XML into an object.

For the same reason, you can't serialize properties that return interfaces: the deserializer wouldn't know what concrete class to instantiate.


Oh here's a good one: since the XML serialization code is generated and placed in a separate DLL, you don't get any meaningful error when there is a mistake in your code that breaks the serializer. Just something like "unable to locate s3d3fsdf.dll". Nice.