使用无效的枚举值序列化对象

时间:2012-04-02 09:43:46

标签: c# serialization

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

的枚举
Public enum EmployeeType
{
    Standard = 0,
    TeamLeader = 105
}

自应用程序发布以来,Web服务类库已对其进行了更改 - 添加了新的枚举值。 (SeniorManager = 110

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

我想要实现的是仍然能够序列化对象,但是忽略无效的枚举值,或用有效的替换它(理想情况下{ {1}})。

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

注意:

  • 上述枚举/值是出于问题的目的而不是实际的枚举。
  • 对于应用程序而言,值将使用不正确的值序列化这一事实并不重要。

谢谢!

2 个答案:

答案 0 :(得分:2)

我最终使用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.IsDefined with flagged enums

另外,Darin Dimitrovthis question中的回答归功于我指向JSON.NET和JsonConverter。

答案 1 :(得分:1)

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

无论如何,你可以试试这个工作:

  1. 真实字段,不是序列化

    [NonSerialized]
    public EmployeeType RealType {get; set;} 
    
  2. 如果Realfield是SeniorManager或实际的RealField值,那么将被序列化的假字段返回标准

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