使用 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
}
我预计消息令牌是:
"Some MessagernParameter name: argument"
正如codefuller所指出的,ArgumentNullException
实现了ISerializable
,并且是罪魁祸首。我可以使用自定义JsonSerializerSettings
禁用此功能。
但是,应用程序需要序列化任何对象,包括具有ArgumentNullException
属性的对象。我宁愿避免忽略ISerialiable
,除非它会带来问题。
我的两个解决方案都包括自定义JsonConverter
。
解决方案 1:集中式 Json 序列化程序
- 创建要添加到
JsonSerializer.Converters
的静态JsonConverters
列表 - 包括显式处理
ArgumentNullException
的ExceptionConverter
- 在我需要序列化的任何地方,请确保我的
JsonSerializer
包含这些转换器
缺点:其他开发人员必须严格确保他们在执行的任何序列化中都包含这些转换器。
解决方案 2:重写参数空异常
我可以创建一个CustomArgumentNullException
类,并使用JsonConvert
属性对其进行标记以利用我的自定义转换器。
缺点:其他开发人员必须严格确保他们提出CustomArgumentNullException
而不是ArgumentNullExcpetion
。
如愿以偿的解决方案
我很想以某种方式用指向我的自定义转换器的JsonConverter
属性标记现有ArgumentNullException
。有没有办法在 Json.NET 代码库中实现这一点?
Exception 类实现ISerializable
接口。默认情况下,对于此类对象 Json.Net 使用ISerializable.GetObjectData()
方法进行数据序列化。换句话说ArgumentNullException
类本身控制其数据的序列化方式。它内部的某个地方有一个逻辑,该逻辑仅序列化传递给构造函数的实际消息,而不序列化Parameter name: argument
部分。
您可以更改此 Json.Net 行为,并避免使用以下JsonSerializerSettings
GetObjectData()
:
var settings = new JsonSerializerSettings()
{
ContractResolver = new DefaultContractResolver()
{
IgnoreSerializableInterface = true,
},
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
var json = JsonConvert.SerializeObject(new ArgumentNullException("argument", "Some Message"), settings);
但是,在这种情况下,序列化字段集将与原始 json 不同。检查它是否真的适合您的需求。