忽略反序列化期间目标模型类中不存在的JSON枚举值

时间:2017-06-13 17:33:51

标签: c# json serialization json.net deserialization

所以我正在使用C#编写API包装器,我使用Newtonsoft.Json库将JSON数据反序列化为响应模型类。在响应模型类中,我有一个子项列表,每个子项都包含一个子项列表。这些定义如下:

public List<StatModel> Stats { get; set; }

每个StatModel都有一个基本上等于名称的属性:

public Stat Stat { get; set; }

这些是自动反序列化的,因为每个Stat都在这样的枚举中定义:

[EnumMember(Value = "Avg Walk Distance")]
AverageWalkDistance,

现在问题是,如果实际API中的某些内容发生了变化,则包装器不起作用,因为它没有指定Stat的定义。所以这意味着如果他们向API添加一个新的Stat,那么在我为它手动添加定义之前,包装器将无法工作,就像在上面的代码块中一样。

所以问题是,如何忽略没有相应Stat属性的值,或者我可以以某种方式重新设计整个事情,这样就不会发生?我猜我必须自己定义所有新值。

以下是关于GitHub的项目,以便更好地理解我的意思:https://github.com/eklypss/PUBGSharp

请求者执行反序列化并返回一个StatResponse,它包含一个名为StatsRoot的子项列表,每个子项都有自己的StatModel列表,这些StatModel是导致此问题的实际stat对象。每种类型的Stat都在Enum / Stat.cs文件中定义。

3 个答案:

答案 0 :(得分:1)

如果您不想创建自己的StringEnumConverter容错版本,可以使用Json.NET的exception handling功能:

public class StatModel
{
    const string StatName = "label";

    [JsonProperty(StatName)]
    [JsonConverter(typeof(StringEnumConverter))]
    public Stat Stat { get; set; }

    public string Value { get; set; }
    public int? Rank { get; set; }
    public double? Percentile { get; set; }

    [OnError]
    void OnError(StreamingContext context, ErrorContext errorContext)
    {
        if (errorContext.OriginalObject == this && StatName.Equals(errorContext.Member))
        {
            errorContext.Handled = true;
        }
    }
}

在反序列化StatModel或其任何嵌套对象时抛出异常时,将调用其OnError()方法来处理错误。该方法检查是否抛出了异常

  1. 反序列化此特定对象时,AND
  2. 反序列化“label”成员时。
  3. 如果是,则吞下异常。您还可以借此机会在模型中设置一个标志,指示Stat属性无效。

答案 1 :(得分:0)

您可以json.net忽略遗失的成员。

var settings = new JsonSerializerSettings
{
    NullValueHandling = NullValueHandling.Ignore,
    MissingMemberHandling = MissingMemberHandling.Ignore
};

var json = JsonConvert.DeserializeObject<MyClass>(jsonStr, settings);

答案 2 :(得分:0)

请参阅下面的问题,这家伙有同样的问题。

How can I ignore unknown enum values during json deserialization?

然而,

即使你以某种方式设法忽略新的Stat,它也不适合你的包装器,因为你的包装器的消费者需要等待你添加新的Enum

因此,

如果我是你,我会考虑将StatEnum更改为string,因此每当新的Stat出现时,您都不需要更改任何内容或消费者你的包装,不必等待。