C# Enum XML Serialization - Instance validation error: 'value' is not a valid value for ObjectType.

When using serialization in C# I've found a very annoying problem that doesn't seem to have a good solution. If you rename or remove an enum value the XML serializer reports the following error when you try and deserialize and existing object that uses that enum value.

Instance validation error: 'value' is not a valid value for ObjectType.

I already use code to standardise enums to "Unknown" on the set accessor if an unknown value is passed in. This however isn't good enough for the XML serializer which pre-checks all possible values.

Take the following example where bicycle has been spelled incorrectly but we already have XML data in customer environments with the incorrect spelling so we can't just rename it.
 

/// <summary>
/// The type of vehicle.
/// </summary>
public enum VehicleType
{

    /// <summary>
    /// The vehicle type is unknown.
    /// </summary>
    Unknown,

    /// <summary>
    /// A normal car.
    /// </summary>
    Car,

    /// <summary>
    /// A bike.
    /// </summary>
    Bicyle,

}


I wanted to override the serialization process to correct the value however this doesn't seem possible. I looked at IXmlSerializable however this looked way too much complexity.

You have the simple option of adding another value however then using intellisense you get

VehcileType.Bicyle and VehicleType.Bicycle next to each other which makes it likely you'll make a mistake in enum selection.

I looked at adding the [Obsolete] attribute to the incorrect spelling however the XML serializer automatically ignores values marked as obsolete....

The workaround I completed was as follows

  • Rename the incorrect enum value with a nice obvious obsolete prefix
  • Use the XmlEnum attribute to use the spelling mistake
  • Use the property accessor for the enum to correct the value
This isn't ideal but it does mean the XML serializer doesn't break and values will be corrected over time and then the property can be removed. I hope this is useful to someone else as this problem is really quite annoying!


/// <summary>
/// The type of vehicle.
/// </summary>
public enum VehicleType
{

    /// <summary>
    /// The vehicle type is unknown.
    /// </summary>
    Unknown,

    /// <summary>
    /// A normal car.
    /// </summary>
    Car,
 
    /// <summary>
    /// WARNING: this property is obsolete.
    /// </summary>
    [XmlEnum("Bicyle")]
    ObsoleteBicyle,

    /// <summary>
    /// A bike.
    /// </summary>
    Bicycle,
 
}




/// <summary>
/// Gets or sets the type of vehicle
/// </summary>
public VehicleType VehicleType
{
    get { return _VehicleType; }
    set
    {
        if (value == xmltest.VehicleType.ObsoleteBicyle) { value = xmltest.VehicleType.Bicycle; }
        _VehicleType = value;
    }
}
private VehicleType _VehicleType = VehicleType.Unknown;



Comments

Post a Comment

Popular posts from this blog

Windows Server 2016, 2019, 2022, Windows 10 and Windows 11: Date and time "Some settings are managed by your organization".

TFTPD32 or TFTPD64 reports Bind error 10013 An attempt was made to access a socket in a way forbidden by its access permissions.

Windows Server 2019 desktop icons such as My Computer, Windows cannot access the specified device, path, or file.