Jonas Stawski

Everything .NET and More

Serializing Objects with Enums

Take into consideration the following entity:

public class CompositeType
{   
    public bool BoolValue { get; set; }
    public string StringValue { get; set; }   
    public EnumType VehicleType { get; set; }
}
 
public enum EnumType
{
    Car = 0,
    Truck = 1
}

CompositeType is just a class that holds three public properties of which VehicleType is of type EnumType, an enum.

CompositeType ct = new CompositeType();
ct.BoolValue = true;
ct.StringValue = "Hello World!";
ct.VehicleType = (EnumType)1;
 
XmlSerializer x = new XmlSerializer(ct.GetType());
x.Serialize(Console.Out, ct);

The code above instantiates a new CompositeType entity, sets some values and serializes it into XML. The result looks something like this:

image

That is cool, but I haven't shown anything new! Here's something I just learned a few days ago. If we debug the program and hover over the VehicleType property we see that is set to Truck:

image

If I now set it equals to 2 (note: 2 doesn't exist in the Enum declaration) and debug look at the value:

image

ct.VehicleType no longer equals to an EnumType value, it now equals to an integer and in this case it equals to 2. My first instinct was why is this not throwing an exception, but then I realized that an enum is nothing other than strongly typed constants with integral values. Nonetheless I was still surprised.

Where am I going with all this? If we continue the execution of the last code it throws the exception: "Instance validation error: '2' is not a valid value for EnumType." So my next question comes as how should an enum be serialized? If .NET allows you to set an enum equal to a number that doesn't exist, then it should also allow you to serialize it. If you pay close attention to the print screen above, the enum is being serialized with the literal value (Truck) instead of the integer value (1) and when VehicleType is equal to an integer that doesn't exist in the enum declaration it can't find the corresponding literal value and thus it blows up.

I believe in consistency and therefore I believe the enum should have been serialized as an integer. If it did then you wouldn't be reading about this because there would have not been any problems. The truth of the matter is that it doesn't serialize as an integer and we currently have 2 options:

1. Implement IXmlSerializable and manually serialize every property, which can be a pain if your object is huge and contains more nested objects or

2. Follow me on my quest to have a new Attribute for Enum members which tells .NET how to serialize themselves. You can vote on this issue by following this link: https://connect.microsoft.com/wcf/feedback/ViewFeedback.aspx?FeedbackID=364337

Please note that the code example I give here are for simplicity. I did actually run into this issue with WCF. We set the enum with the value from the database and due to versioning issues, the database contained a value not declared in the enum. The code was blowing up when WCF was trying to serialize the object to pass it back to the client.

Thanks for your support!

Add comment

biuquote
Loading