XmlSerializer: How to Deserialize an enum value that no longer exists

随声附和 提交于 2019-12-29 08:32:36

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!