Newtonsoft Json.Net中的MissingMemberHandling.Error拦截器

时间:2018-07-08 23:12:43

标签: json.net

(最后一段中的思想使我改变了这个问题的主题)

我想知道是否有人知道Json.Net内置的任何功能,该功能允许您访问部分(首次通过)构造的对象以及json数据。

因此,只有在默认行为中未对json的某些部分进行反序列化的情况下,我才能够进行额外的处理以获得所需的输出?

ContractResolver仅能访问目标类型,JsonConverter s能够访问json和目标类型,但必须创建该类型的实例,并且对{{ 1}}通常可以运行的方法。

我曾尝试在源代码中查找此类内容,但没有看到任何调用。但是以为我会看看是否有人知道这样的功能。


我似乎经常发现想要对95%的对象使用默认的反序列化行为,但是只是做不同的一部分,或者进行少量的后处理。想要设置serializer时,这变得特别棘手,因为任何自定义MissingMemberHandling = MissingMemberHandling.Error都会绕过该检查(除非您手动执行所有JsonConverter调用,而不是reader.Read()) / p>


对于一个特定的示例,我希望能够将这两个json主体反序列化为同一模型:

JObject.Load(reader)

我的第一个尝试是建立一个自定义{ "Metadata": { "DateAccessed": "2018-07-06 15:59:55" }, "Data": { "2018-07-06 15:59:55": { "value": 324 }, "2018-07-05 15:59:55": { "value": 312 } } } { "Meta Data": { "DateAccessed": "2018-07-06 15:59:55" }, "Processed": { "2018-07-06 15:59:55": { "value": 12.34 }, "2018-07-05 15:59:55": { "value": 11.12 } } } ,它可以识别自定义属性ContractResolver[MultiNameProperty("Metadata", "Meta Data")],但这是不可持续的。

最好设置它,以便默认情况下可以工作,但是与其[MultiNameProperty("Data", "Processed")]引发JsonSerializationException的麻烦,不如先尝试为此调用处理程序……

但是除了将其添加到当前内置的Newtonsoft Json.Net中,还有其他选择吗?

2 个答案:

答案 0 :(得分:0)

您可以先将JSON解析为JObject,然后对其进行调整并将其反序列化为所需的模型:

public static Model Parse(string jsonString){
    var obj = JObject.Parse(jsonString);    
    Normalize(obj);
    return obj.ToObject<Model>();
}

public static void Normalize(JObject obj){
    if (obj["Metadata"] == null)
    {
        obj["Metadata"] = obj["Meta Data"];
        obj.Remove("Meta Data");
    }

    if (obj["Data"] == null)
    {
        obj["Data"] = obj["Processed"];
        obj.Remove("Processed");
    }
}

示例:https://dotnetfiddle.net/TtMYaq

答案 1 :(得分:0)

我想说,最好的,更通用的选择是使用[JsonExtensionDataAttribute] private IDictionary<string, JToken> _additionalData处理未知成员,并使用[OnDeserialized]进行后处理

我最终遇到的问题的解决方案是building a custom JsonConverter,只是期望在这种情况下,我得到的所有响应上都有2个顶级属性,允许第二个属性具有任何名称它想要拥有