假设我有一个示例类:
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());
我得到这个错误:
无法将当前JSON数组(例如[1,2,3])反序列化为类型"FlagEnumerable",因为该类型需要JSON基元值(例如字符串、数字、布尔值、null)才能正确反序列化。要修复此错误,请将JSON更改为JSON基元值(例如,字符串、数字、布尔值、null),或者将反序列化的类型更改为数组或实现集合接口(例如,ICollection、IList)的类型,如可以从JSON数组反序列化的List。JsonArrayAttribute也可以添加到类型中,以强制它从JSON数组反序列化。
感谢您的帮助!抱歉,如果不清楚,请随时提问。
我同样需要序列化可枚举为字符串数组的标志。我认为自从你发布这个问题以来,有些事情发生了变化。我目前能够通过使用以下转换器来实现这一点:
[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());
}
}
基于这个问题的最佳答案:枚举作为字符串的JSON序列化您需要的是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"
}
请注意,在反序列化时似乎没有必要传入StringEnumConverter
——上面的JSON块可以反序列化。