实例验证错误:*不是*的有效值

时间:2014-03-07 08:57:30

标签: c# xml-deserialization

我正在尝试反序列化一个XML字符串,其中元素的值不在我的Enum值的范围内。

Public enum MyEnum
{
    Unknown,
    Car,
    Bicycle,
    Boat
}

[SerializableAttribute()]
public class MyClass
{
    private string _id;
    private MyEnum _myEnum;

    public string ID
    {
        get { return _id; }
        set { _id = value; }
    }

    public MyEnum EnumValue
    {
        get { return _myEnum; }
        set { _myEnum = value; }
    }

    public MyClass(string id)
    {
        this._id = id;
    }

    public MyClass() : this("") { }
}

如果我尝试反序列化后面的字符串(注意Plane作为枚举值):

<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><MyClass><ID>1234567890123456789</ID><EnumValue>Plane</EnumValue></MyClass>

然后我的反序列化会抛出异常,甚至在它为EnumValue命中我的公共字段之前,会出现以下异常消息:

  

实例验证错误:'Plane'不是EnumValue的有效值

是否可以返回EnumValue的默认值,如果我尝试在XML中解析的值不支持EnumValue? 例如。对于此处提供的XML字符串,EnumValue应设置为“Unknown”。

4 个答案:

答案 0 :(得分:5)

[XmlIgnore]
public MyEnum EnumValueReal
{
    get { return _myEnum; }
    set { _myEnum = value; }
}

public string EnumValue
{
     get
     {
         return EnumValueReal.ToString();
     }

     set
     {
         MyEnum result = MyEnum.Unknown;
         Enum.TryParse(value, true, out result);

         EnumValueReal = result;
     }
}

答案 1 :(得分:1)

其他方法是将EnumValue声明为字符串并将EnumValue属性中的值解析为另一个属性中的MyEnum(使用自定义逻辑)。另一个属性应标记为不可序列化。

public string EnumValue
{
    get { return _myEnum; }
    set { _myEnum = value; }
}

[NonSerialized]
public MyEnum EnumValueTyped {
  get {
    MyEnum value;
    if (Enum.TryParse<MyEnum>(EnumValue, out value)) {
      return value;
    }
    return MyEnum.Unknown;
  }
  set {
    EnumValue = value.ToString();
  }
}

答案 2 :(得分:1)

恕我直言,最“合适”的解决方案是让EnumValue属性可以为空 - 因为你得到的错误(和MyEnum.Unknown)暗示这个属性可能没有值。

代码如下:

public enum MyEnum
{
    Car,
    Bicycle,
    Boat
}

[Serializable()]
public class MyClass
{
    private string _id;
    private MyEnum? _myEnum;

    public string ID
    {
        get { return _id; }
        set { _id = value; }
    }

    public MyEnum? EnumValue
    {

        get { return _myEnum; }
        set { _myEnum = value; }
    }

    public MyClass(string id)
    {
        this._id = id;
    }

    public MyClass() : this("")
    {
    }
}

答案 3 :(得分:0)

是的,但我认为你不能再使用SerializableAttribute了。

您应该实现ISerializable并提供自己的序列化器/解串器。您可以使用默认的序列化程序(例如,新的BinaryFormatter()。序列化程序()),但您必须实现自定义反序列化。