Serializing Object With Invalid Enum Value

久未见 提交于 2019-12-23 02:31:40

问题


I have a Windows Phone 7 project that connects to a .NET web service to fetch data on demand. Both the WP7 project and the web service use a copy of the same c# class library. Part of this library is an enum of EmployeeType:

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

Since the app was released, the web service class library has had a change made to it - adding a new enum value. (SeniorManager = 110)

Therefore, when I receive an object on the phone with a property containing the new enum value, I get a SerializationException when attempting to add it to IsolatedStorage. This is because the new enum value cannot be serialized, as the WP7 class library has not had the same update made to it and the enum value does not exist.

What I would like to achieve is to still be able to serialize the object, but ignore the invalid enum value, or replace it with a valid one (ideally Standard = 0).

This will enable me to handle any future additions made to the web service enum, without breaking the functionality of the app.

Notes:

  • The enum/values above are contrived for the purposes of the question and not the actual enum in question.
  • The fact that the value would be serialized with an incorrect value is unimportant for the purposes of the app.

Thanks!


回答1:


I ended up using JSON.NET to deserialize the data from the server (reader is a StreamReader for the response stream. TResponse is the generic response expected from the server.):

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

The JsonEnumTypeConverter class checks that the enum value returned from the server is valid for the given type. If not, then it's defaulted to zero. (Always present on enums). This class is defined as follows:

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));
    }
}

Note that I use the custom IsFlagDefined method, rather than Enum.IsDefined as my enums include [Flags] attributes which Enum.IsDefined does not handle. (Source: Enum.IsDefined with flagged enums)

Also, credit to Darin Dimitrov's answer in this question for pointing me towards JSON.NET and the JsonConverter.




回答2:


I don't understand why you don't update the reference to the WebService in WP7 project, so that you will be able to serialize it.

Anyway, you can try this workaorund:

  1. The real field, not to be serialized

    [NonSerialized]
    public EmployeeType RealType {get; set;} 
    
  2. A fake field, that will be serialized returns Standard if Realfield is SeniorManager or actual RealField value

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


来源:https://stackoverflow.com/questions/9974127/serializing-object-with-invalid-enum-value

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