Как десериализовать массив перечислений с помощью 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"
  ]
 }