JsonSerializerSettings中指定的错误是否捕获所有异常

时间:2016-07-19 11:36:27

标签: c# json serialization json.net deserialization

我尝试从Newtonsoft Documentation

实现错误处理代码

我正在使用以下JsonSerializerSettings

errors = new JsonErrors();
jsonSerializerSettings = new JsonSerializerSettings
{
    Error = delegate (object sender, ErrorEventArgs args)
    {
        errors.Add(args.ErrorContext.Error.Message);
        args.ErrorContext.Handled = true;
    }

};

我使用以下代码反序列化响应。

try
{
    deserializedObject = JsonConvert.DeserializeObject(response, jsonSerializerSettings);
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
    throw;
}

如果在响应字符串的末尾添加一些额外的字符,我希望捕获反序列化异常但实际上我看到相关的错误添加到JsonErrors对象。

我能否确定反序列化/序列化引发的任何错误都会被JsonSerializerSettings机制捕获。 我可以删除代码中的try a catch吗?

2 个答案:

答案 0 :(得分:2)

理论上,所有异常都应该被捕获并传递给处理程序(cannot be caught例外StackOverflowException除外。)如果你转到github sourcesearch for IsErrorHandled您将看到捕获所有类型的异常,例如here

        catch (Exception ex)
        {
            if (IsErrorHandled(null, contract, null, reader as IJsonLineInfo, reader.Path, ex))
            {
                HandleError(reader, false, 0);
                return null;
            }
            else
            {
                // clear context in case serializer is being used inside a converter
                // if the converter wraps the error then not clearing the context will cause this error:
                // "Current error context error is different to requested error."
                ClearErrorContext();
                throw;
            }
        }

话虽如此,实际上可能存在不起作用的边缘情况。例如,在previous answer中我注意到无法处理从根对象OnSerializing事件抛出的异常 - 尽管这在当前版本中似乎不可重现(9.0)Json.NET。但即使在当前版本中,如果尝试为根对象创建合同而抛出异常,Json.NET也不会捕获并处理它。这可能是因为有错误的custom contract resolver,或者是因为将序列化属性应用于根对象时出错。例如,尝试将以下序列化或反序列化为根对象:

public class BadExtensionData
{
    Dictionary<string, object> extensionData;

    [JsonExtensionData]
    public Dictionary<string, object> ExtensionData { set { extensionData = value; } }
}

将导致未处理的异常:

Newtonsoft.Json.JsonException: Invalid extension data attribute on 'BadExtensionData'. Member 'ExtensionData' must have a getter.

因此,您可能希望保留外部try / catch以防万一(甚至report an issue用于无法处理的异常)。

最后,请注意捕捉和吞咽所有异常都被视为bad practice

答案 1 :(得分:1)

在快速源代码检查后,我倾向于说下面的句子是真的:

如果JsonSerializerSettings正确(即没有令人讨厌的空引用,并且配置的错误处理程序的Handled属性设置为true) 并且输入字符串不为空(仅用于反序列化),则try-catch块是多余的。