如何使用Json.Net反序列化枚举数组?

pan*_*zza 19 c# json.net windows-phone-8

我有一个像这样的JSON:

[{ 
    "agencyId": "myCity",
    "road": {
    "note": "",
        "lat": "45.321",
        "lon": "12.21",
        "streetCode": "290",
        "street": "street1",
        "fromNumber": "",
        "toNumber": "",
        "fromIntersection": "",
        "toIntersection": ""
    },
    "changeTypes": ["PARKING_BLOCK", "ROAD_BLOCK"],
},]
Run Code Online (Sandbox Code Playgroud)

和这样的一个类:

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; }
}
Run Code Online (Sandbox Code Playgroud)

AgencyType是枚举,AgencyId的反序列化和序列化工作.

ChangeType是另一个枚举,但ChangeTypes的反序列化和序列化不起作用.我假设原因是ChangeTypes是一个枚举值数组.

问题是:如何反序列化/序列化ChangeTypes字段,或者通常是枚举值数组?

我尝试定义自己的字段转换器,名为ChangeTypeConverter,并将StrinEnumConverter更改为ChangeTypeConverter for ChangeTypes字段,但在ReadJson函数中,reader的值为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);
    }
}
Run Code Online (Sandbox Code Playgroud)

Bri*_*ers 45

StringEnumConverter预期只有一个枚举值.因为ChangeTypes是一个数组,所以需要以不同的方式注释属性以使其工作.

试试这个:

[JsonProperty("changeTypes", ItemConverterType=typeof(StringEnumConverter))]
public ChangeType[] ChangeTypes { get; set; }
Run Code Online (Sandbox Code Playgroud)

  • 代替该属性上的JsonProperty,一种更干净的方法是**在枚举本身上使用StringEnumConverter属性**。我更喜欢它,因为我不想在属性名称中使用别名,并且如果我们需要使用ItemConverterType,那么唯一的方法是使用JsonProperty和不必要的提供别名。 (2认同)

Jim*_*dhi 8

无需编写自定义JsonConverter即可对Enum数组进行序列化/反序列化。与其装饰父模型中的单个属性,不如使用StringEnumConverter JsonConverter属性装饰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
}
Run Code Online (Sandbox Code Playgroud)

输出json:-

 {
   "name": "",
   "shelter": "Indoor",
    "shelters": [
       "Indoor",
       "Outdoor"
  ]
 }
Run Code Online (Sandbox Code Playgroud)

  • 请注意,可能并不总是可以直接使用属性来修饰枚举,例如,如果它是在第三方库中定义的。一个很好的例子是 [`System.Windows.Media.Colors`](https://learn.microsoft.com/en-us/dotnet/api/system.windows.media.colors?view=netframework-4.8) (3认同)