问题
I am using the XMLSerializer to save this class to a file. The class has a string and an enum as shown below:
public class IOPoint
{
string Name {get; set;}
TypeEnum {get; set;}
}
public enum TypeEnum
{
Temperature,
Pressure,
Humidity,
}
When serialized it looks like this.
<IOPoint>
<Name>Relative Humidity</Name>
<TypeEnum>Humidity</TypeEnum>
</IOPoint>
I've been serializing and deserializing this object with no problems for several versions. I no longer want to support Humidity, so I removed it from the enum. However, this causes an exception when deserializing from XML because the value in the TypeEnum field, Humidity, is not a valid value for the TypeEnum. This makes sense, but how to handle this?
What I'd like to do is just ignore this error. And leave the value as null. I've tried implementing the OnUnknownElement XmlDeserilizationEvent class. Unfortunately, this does not catch this error.
Any ideas on how to catch and ignore this error (I can clean up after the deserialization is complete).
Mitch
回答1:
You can mark the member Obsolete
public enum TypeEnum
{
Temperature,
Pressure,
[Obsolete]
Humidity
}
回答2:
It’s generally considered bad practice to remove an enumeration member after your library is already in use. Why don’t you leave the member in place, but mark it with the [Obsolete]
attribute to prevent future use? Specifying the ObsoleteAttribute(string,bool) constructor’s second parameter as true
would cause a compile-time error if the marked member is accessed.
public enum TypeEnum
{
Temperature,
Pressure,
[Obsolete("It's always sunny in Philadelphia", true)]
Humidity,
}
To circumvent the error when checking deserialized values, you could compare against the underlying value: typeEnum == (TypeEnum)2
.
回答3:
You can use attributes to change node names around and hide elements from xml serialization, parsing just that one element manually:
public class IOPoint
{
public string Name {get; set;}
[XmlIgnore]
public TypeEnum TypeEnum {get; set;}
[XmlElement("TypeEnum")]
public string LegacyTypeEnum
{
get { return this.TypeEnum.ToString(); }
set
{
try
{
this.TypeEnum = (TypeEnum)Enum.Parse(typeof(TypeEnum),value);
}
catch(ArgumentException)
{
// Handle "Humidity"
}
catch(OverflowException)
{
}
}
}
}
Per comments there appears to be some confusion; here is a worked example as a Visual Studio 2010 project. This approach is a simple way of manually parsing only one property of an object (still leveraging the XmlSerializer to do the XML parsing).
回答4:
You could implement IXmlSerializable, where you can use something like TryParse for the enum.
But I agree with the other posters using the Obsolete attribute.
来源:https://stackoverflow.com/questions/10708240/xmlserializer-how-to-deserialize-an-enum-value-that-no-longer-exists