我有一个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
是响应流的StreamReader
。TResponse
是服务器预期的通用响应。):
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的引用,这样你就可以序列化它了。
不管怎样,你可以试试这个方法:
-
真实字段,不需要序列化
[NonSerialized] public EmployeeType RealType {get; set;}
-
如果Realfield是SeniorManager或实际Realfield值,则将序列化的伪字段将返回Standard
public EmployeeType Type { get{ if (RealType== EmployeeType.TeamLeader) return EmployeeType.TeamLeader; else return EmployeeType.Standard; } set{RealType=value;} }