正在序列化具有无效枚举值的对象

本文关键字:枚举 对象 无效 序列化 | 更新日期: 2023-09-27 18:29:40

我有一个Windows Phone 7项目,它连接到.NET web服务以按需获取数据。WP7项目和web服务都使用同一个c#类库的副本。这个库的一部分是EmployeeType:的枚举

Public enum EmployeeType
{
    Standard = 0,
    TeamLeader = 105
}

自该应用程序发布以来,web服务类库进行了更改,添加了一个新的枚举值。(SeniorManager = 110

因此,当我在电话上收到一个具有包含新枚举值的属性的对象时,当我试图将其添加到IsolatedStorage时,我会得到一个SerializationException。这是因为无法序列化新的枚举值,因为WP7类库没有对其进行相同的更新,并且该枚举值不存在。

我希望实现的是仍然能够序列化对象,但忽略无效的枚举值或将其替换为有效的枚举值(理想情况下为Standard = 0)。

这将使我能够处理未来对web服务枚举的任何添加,而不会破坏应用程序的功能。

注:

  • 上面的枚举/值是为问题的目的而设计的,而不是所讨论的实际枚举
  • 对于应用程序而言,值将使用不正确的值进行序列化这一事实并不重要

谢谢!

正在序列化具有无效枚举值的对象

我最终使用JSON.NET从服务器反序列化数据(reader是响应流的StreamReaderTResponse是服务器预期的通用响应。):

var serializer = new JsonSerializer();
serializer.Converters.Add(new JsonEnumTypeConverter());
this.Response = serializer.Deserialize<TResponse>(new JsonTextReader(reader));

JsonEnumTypeConverter类检查从服务器返回的枚举值是否对给定类型有效。如果不是,则默认为零。(始终存在于枚举中)。此类定义如下:

private class JsonEnumTypeConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType.IsEnum;
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        try
        {
            var value = Enum.Parse(objectType, reader.Value.ToString(), true);
            if (IsFlagDefined((Enum)value))
            {
                return value;
            }
            else
            {
                return 0;
            }
        }
        catch (Exception)
        {
            return 0;
        }
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteValue(value);
    }
    private static bool IsFlagDefined(Enum e)
    {
        decimal d;
        return (!decimal.TryParse(e.ToString(), out d));
    }
}

请注意,我使用自定义的IsFlagDefined方法,而不是Enum.IsDefined,因为我的枚举包括Enum.IsDefined不处理的[Flags]属性。(来源:Enum.Is用标记的枚举定义)

此外,感谢Darin Dimitrov在这个问题中的回答,他向我介绍了JSON.NET和JsonConverter。

我不明白你为什么不在WP7项目中更新对WebService的引用,这样你就可以序列化它了。

不管怎样,你可以试试这个方法:

  1. 真实字段,不需要序列化

    [NonSerialized]
    public EmployeeType RealType {get; set;} 
    
  2. 如果Realfield是SeniorManager或实际Realfield值,则将序列化的伪字段将返回Standard

    public EmployeeType Type 
     {
      get{
           if (RealType== EmployeeType.TeamLeader)
              return  EmployeeType.TeamLeader;
           else 
              return  EmployeeType.Standard;
         } 
      set{RealType=value;}
     }