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

标签 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 吗?

最佳答案

理论上,所有异常都应该被捕获并传递给处理程序(除了 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 抛出的异常无法处理 root 对象 的事件——尽管这在 Json.NET 的当前版本 (9.0) 中似乎不可重现。但即使在当前版本中,如果在尝试为根对象创建契约时抛出异常,Json.NET 也不会捕获并处理它。这可能是由于 buggy 导致的 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 .

关于c# - JsonSerializerSettings 中指定的错误是否捕获所有异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38457422/

相关文章:

c++ - *&在C语言中是什么意思?

serialization - 如何使用 RestSharp 将对象发布(作为 XML)到我的 ApiController?

c# - Resharper 建议字符串文字是可本地化的

c# - REST 服务和大文件

c++ - 在 Qt 插件类中读取自己的元数据

json - 如何提供 JSON 数组作为 cobra cli 的参数

c# - 为什么不推荐使用私有(private)访问器?

c# - 将 StringBuilder 传递给需要 char 指针的 DLL 函数

javascript - 在我的 Shopify Liquid 主题中添加并解析我自己的 JSON 对象

java - 通过 ByteBuffer 和 CQL 3 将 Java 对象序列化到 Cassandra 1.2