2013-02-05 20 views
1

比方说,我有一个例子类:应用全局转换器Json.NET

public class SomeObject 
{ 
    private FlagEnumerable _someFlagValue = FlagEnumerable.Flag1; 

    public SomeObject() 
    { 
    } 

    [DataMember(Name = "someFlagValue")] 
    [Browsable(false)] 
    public FlagEnumerable SomeFlagValue 
    { 
     get { return _someFlagValue; } 
     set { _someFlagValue= value; } 
    } 
} 

这是我怎么形容我的FlagEnumerable

[DataContract] 
[Flags] 
[JsonConverter(typeof(JsonEnumConverter))] 
public enum FlagEnumerable 
{ 
    [EnumMember] 
    Flag1 = 1, 

    [EnumMember] 
    Flag2 = 2, 

    [EnumMember] 
    Flag3 = 4 
} 

另外,我有一个自定义JSON转换器将枚举转换为字符串,将枚举标记为字符串数组,反之亦然。

此代码工作良好,并成功反序列化JSON例如:

{ 
    someFlagValue: [ 
     "Flag1" 
    ] 
} 

的问题是如何将一个全球性的转换器将JsonSerializer?当我删除从FlagEnumerable[JsonConverter(typeof(JsonEnumConverter))],然后通过调用

MyJsonSerializer.Converters.Add(new JsonEnumConverter()); 

我得到这个错误添加:

Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'FlagEnumerable' because the type requires a JSON primitive value (e.g. string, number, boolean, null) to deserialize correctly. To fix this error either change the JSON to a JSON primitive value (e.g. string, number, boolean, null) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.

任何帮助表示赞赏!对不起,如果不清楚,随时提问。

+0

嘿,你有没有想过如何实现这一目标?我正在寻找完全相同的东西(我不想装饰我的所有枚举,并且更喜欢在全局范围内进行) – amhed

回答

0

根据此问题的最高评分回答:JSON serialization of enum as string您需要的是StringEnumConverter

使用时,该代码:

SomeObject someObject = new SomeObject() { SomeFlagValue = FlagEnumerable.Flag3 }; 
string json = JsonConvert.SerializeObject(someObject, 
    Newtonsoft.Json.Formatting.Indented, 
    new Newtonsoft.Json.Converters.StringEnumConverter()); 

会产生这样JSON:

{ 
    "SomeFlagValue": "Flag3" 
} 

注意,它并不显得neccessary反序列化时,在StringEnumConverter传递 - 的该块上面的JSON可能会被反序列化。

1

我有相同的需要序列化作为字符串数组enumerable标志。我认为自你发布问题以来发生了一些变化。 我目前能够通过使用以下转换器实现此目的:

[Flags] 
enum FlagEnumerable 
{ 
    Flag1 = 1, 
    Flag2 = 2, 
    Flag3 = 4 
} 

class FlagsEnumConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return objectType.IsEnum && objectType.GetCustomAttributes(typeof(FlagsAttribute), false).Any(); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     var values = serializer.Deserialize<string[]>(reader); 

     return values 
      .Select(x => Enum.Parse(objectType, x)) 
      .Aggregate(0, (current, value) => current | (int) value); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     var enumArr = Enum.GetValues(value.GetType()) 
      .Cast<int>() 
      .Where(x => (x & (int) value) == x) 
      .Select(x => Enum.ToObject(value.GetType(), x).ToString()) 
      .ToArray(); 

     serializer.Serialize(writer, enumArr); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     JsonConvert.DefaultSettings =() => new JsonSerializerSettings() 
     { 
      Converters = new List<JsonConverter>() {new FlagsEnumConverter()} 
     }; 

     var targetObj = new { MyField = FlagEnumerable.Flag1 | FlagEnumerable.Flag3 }; 
     var str = JsonConvert.SerializeObject(targetObj); 
     var deserializedObj = JsonConvert.DeserializeObject(str, targetObj.GetType()); 
    } 
}