Как десериализовать массив перечислений с помощью Json.Net?
У меня такой JSON:
[{
"agencyId": "myCity",
"road": {
"note": "",
"lat": "45.321",
"lon": "12.21",
"streetCode": "290",
"street": "street1",
"fromNumber": "",
"toNumber": "",
"fromIntersection": "",
"toIntersection": ""
},
"changeTypes": ["PARKING_BLOCK", "ROAD_BLOCK"],
},]
и класс такой:
public class AlertRoad : BaseAlert
{
[JsonProperty("agencyId")]
[JsonConverter(typeof(StringEnumConverter))]
public AgencyType AgencyId { get; set; }
[JsonProperty("changeTypes")]
[JsonConverter(typeof(StringEnumConverter))]
public ChangeType[] ChangeTypes { get; set; }
[JsonProperty("road")]
public Road RoadInfo { get; set; }
}
AgencyType - это перечисление, а десериализация и сериализация для работы AgencyId.
ChangeType - это еще одно перечисление, но десериализация и сериализация для ChangeTypes не работают.
Я предполагаю, что причина заключается в том, что ChangeTypes представляет собой массив значений перечисления.
Возникает вопрос: как я могу десериализовать/сериализовать поле ChangeTypes или вообще массив значений перечисления?
Я попытался определить свой собственный преобразователь полей, называемый ChangeTypeConverter, и сменить значение параметра StrinEnumConverter на ChangeTypeConverter for ChangeTypes, но в функции ReadJson значение считывателя равно null.
public class ChangeTypeConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var val = reader.Value;
//val is null?!?
return val;
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(ChangeType);
}
}
Ответы
Ответ 1
StringEnumConverter
ожидает только одно значение перечисления. Поскольку ChangeTypes
- это массив, вам нужно аннотировать свойство немного по-другому, чтобы заставить его работать.
Попробуйте это вместо:
[JsonProperty("changeTypes", ItemConverterType=typeof(StringEnumConverter))]
public ChangeType[] ChangeTypes { get; set; }
Ответ 2
Нет необходимости писать собственный JsonConverter для сериализации/десериализации массива Enum.
Вместо того, чтобы украшать отдельное свойство в родительской модели, просто украсьте Enum атрибутом JsonConverter StringEnumConverter.
Например: -
Следующая модель среды имеет свойство enum объекта Shelter и массив перечислений Shelter []
public class Environment
{
public string Name { get; set; }
public Shelter Shelter { get; set; }
public Shelter[] Shelters { get; set; }
}
[JsonConverter(typeof(StringEnumConverter))]
public enum Shelter
{
Indoor,
Outdoor
}
Выведите json: -
{
"name": "",
"shelter": "Indoor",
"shelters": [
"Indoor",
"Outdoor"
]
}