gpt4 book ai didi

c# - 异常上的 JsonConvert.SerializeObject 丢失消息

转载 作者:行者123 更新时间:2023-12-04 10:39:36 25 4
gpt4 key购买 nike

以前从未见过,基本上我的 MSMQ 调用抛出访问被拒绝,在 Visual Studio 中显示为( exception.ToString())

System.Messaging.MessageQueueException (0x80004005): Access to Message Queuing system is denied.\r\n at System.Messaging.MessageQueue.MQCacheableInfo.get_WriteHandle()\r\n
at System.Messaging.MessageQueue.StaleSafeSendMessage(MQPROPS properties, IntPtr transaction)\r\n at System.Messaging.MessageQueue.SendInternal(Object obj, MessageQueueTransaction internalTransaction, MessageQueueTransactionType transactionType)\r\n at redacted.d__2.MoveNext() in c:\path\file.cs:line 24



现在,这会记录到对包含我的日志记录代码的类库的调用中。

我的代码这样做:
var logMessage = new LogEntry(applicationName, exception, message, level);
LogEntry只是一个简单的老类,将这些东西放入属性中,不做任何其他事情。
var logEntryAsJson = JsonConvert.SerializeObject(logMessage);
此行应将其序列化为 JSON。但是,当它发生时,异常属性更改为:

"Exception":{"NativeErrorCode":-1072824283,"ClassName":"System.Messaging.MessageQueueException","Message":"External component has thrown an exception.","Data":null,"InnerException":null,"HelpURL":null,"StackTraceString":" at System.Messaging.MessageQueue.MQCacheableInfo.get_WriteHandle()\r\n at System.Messaging.MessageQueue.StaleSafeSendMessage(MQPROPS properties, IntPtr transaction)\r\n at System.Messaging.MessageQueue.SendInternal(Object obj, MessageQueueTransaction internalTransaction, MessageQueueTransactionType transactionType)\r\n at redacted.d__2.MoveNext() in c:\path\file.cs:line 24","RemoteStackTraceString":null,"RemoteStackIndex":0,"ExceptionMethod":"8\nget_WriteHandle\nSystem.Messaging, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\nSystem.Messaging.MessageQueue+MQCacheableInfo\nSystem.Messaging.Interop.MessageQueueHandle get_WriteHandle()","HResult":-2147467259,"Source":"System.Messaging","WatsonBuckets":null}



将鼠标悬停在序列化行上的 logMessage 对象上的智能感知显示第一个异常数据。但是当序列化时,它完全改变了它。结果,错误的原因没有被记录下来,所以我在尝试调试它的时候挠了挠头。

这种行为有原因吗?我是否必须强制将异常存储为字符串?

最佳答案

Exception类实现 ISerializable。 Json.NET recognizes this and only serializes the properties specified by the class itself .正如文档解释的那样:

ISerializable

Types that implement ISerializable and are marked with SerializableAttribute are serialized as JSON objects. When serializing, only the values returned from ISerializable.GetObjectData are used; members on the type are ignored. When deserializing, the constructor with a SerializationInfo and StreamingContext is called, passing the JSON object's values.

In situations where this behavior is not wanted, the JsonObjectAttribute can be placed on a .NET type that implements ISerializable to force it to be serialized as a normal JSON object.


MessageQueueException.Message属性在运行时计算并从 .NET 运行时的资源加载一个字符串。 It's not saved by GetObjectData因为实际文本既不需要也不想要 - 在另一个系统上反序列化时, Message将返回可用于该系统的本地化字符串。 External component has thrown an exception来自父级 ExternalException类,将字符串存储在 Message 中但不会覆盖 GetObjectData .
这对于序列化和反序列化来说不是问题,因为数据足以再水合正确的对象。不过,这是 JSON 的一个问题,它不包含类型信息。
可以禁用此行为。一种方法是向类添加属性,这在 BCL 类中是不可能的。另一种可能性是使用 Contract Resolver忽略 ISerializable。 DefaultContractResolver 具有类似 IgnoreSerializableInterface 的属性为了这 :
string json =
JsonConvert.SerializeObject(
exception,
Formatting.Indented,
new JsonSerializerSettings {
ContractResolver = new DefaultContractRresolver {
IgnoreSerializableInterface=true
}}
);

关于c# - 异常上的 JsonConvert.SerializeObject 丢失消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59989006/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com