将ArgumentNullException序列化为Json

3

当使用JSON.NET将System.ArgumentNullException序列化为JSON时,部分消息似乎丢失了:

var json = JsonConvert.SerializeObject(new ArgumentNullException("argument", "Some Message"));

返回:

{
"ClassName":"System.ArgumentNullException",
"Message":"Some Message",
"Data":null,
"InnerException":null,
"HelpURL":null,
"StackTraceString":null,
"RemoteStackTraceString":null,
"RemoteStackIndex":0,
"ExceptionMethod":null,
"HResult":-2147467261,
"Source":null,
"WatsonBuckets":null
}

我原本期望的Message token是:

"Some Message\r\nParameter name: argument"

正如codefuller所指出的那样,ArgumentNullException实现了ISerializable并且是罪魁祸首。我可以通过使用自定义的JsonSerializerSettings来禁用它。
然而,应用程序需要序列化任何对象,包括具有ArgumentNullException属性的对象。我希望避免忽略ISerialiable,除非它会造成问题。
我的两种解决方案都包括一个自定义的JsonConverter。
解决方案1:集中式JsonSerializer - 创建一个静态的JsonConverters列表,添加到JsonSerializer.Converters中 - 包括一个ExceptionConverter,明确处理ArgumentNullException - 在任何需要序列化的地方,确保我的JsonSerializer包含这些转换器
缺点:其他开发人员必须严格确保他们在进行任何序列化时都包含了这些转换器。
解决方案2:覆盖ArgumentNullException
我可以创建一个CustomArgumentNullException类,并使用JsonConvert属性标记它,以利用我的自定义转换器。
缺点:其他开发人员必须严格确保他们引发的是CustomArgumentNullException而不是ArgumentNullExcpetion。
期望的解决方案
我希望能够以某种方式标记现有的ArgumentNullException,使用指向我的自定义转换器的JsonConverter属性。在Json.NET代码库中是否有实现这一点的方法?

我可以通过为ArgumentNullException类创建自定义JsonConverter并将其显式添加到JsonSerializer来解决此问题,但这似乎很丑陋。 - Eric Patrick
1个回答

1
异常类实现了 ISerializable 接口。对于这样的对象,Json.Net 默认使用 ISerializable.GetObjectData() 方法进行数据序列化。换句话说,ArgumentNullException 类控制其自身数据的序列化方式。在其内部,它有一个逻辑,只序列化传递给构造函数的实际消息,而不包括 Parameter name: argument 部分。
您可以通过以下 JsonSerializerSettings 更改此 Json.Net 行为,并避免使用 GetObjectData() 方法:
var settings = new JsonSerializerSettings()
{
    ContractResolver = new DefaultContractResolver()
    {
        IgnoreSerializableInterface = true,
    },
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};

var json = JsonConvert.SerializeObject(new ArgumentNullException("argument", "Some Message"), settings);

然而,在这种情况下,序列化字段的集合将与原始JSON不同。请检查它是否真正适合您的需求。

是的,这给了我一个合理的序列化。然而,我的挑战比我的问题所提出的要广泛一些:在序列化可能包括ArgumentNullException属性的对象时,在整个应用程序堆栈中应用合理的方法是什么?我会适当地编辑问题。谢谢! - Eric Patrick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接