【发布时间】:2023-03-19 13:59:01
【问题描述】:
所以我开始遇到 NServiceBus 的这个问题,它显然会接受消息并序列化它们,但似乎无法反序列化它们以进行处理。我尝试以几种不同的方式在设置中设置序列化程序。以下是我从错误队列中提取的一些异常(堆栈顶部)。
// 不设置序列化器。似乎 NServiceBus 序列化为 XML(如文档所示)但尝试使用 NewtonSoft 进行反序列化
“NServiceBus.ExceptionInfo.StackTrace”: “NServiceBus.MessageDeserializationException:发生错误时 试图从传输消息中提取逻辑消息 7cc546df-09ca-493e-bb6d-a6ce00a6bb10 ---> Newtonsoft.Json.JsonReaderException:遇到意外的字符 解析值时:<. at newtonsoft.json.jsontextreader.parsevalue c: nservicebus.jsonmessageserializer.deserialize ...>
// 将序列化程序设置为正常的 NServiceBus JsonSerializer(如教程中所述)。好像不能反序列化 JObject,因为它没有在扫描中包含 Newtonsoft。但为什么是 它是 JObject 吗?
“NServiceBus.ExceptionInfo.StackTrace”: “NServiceBus.MessageDeserializationException:发生错误时 试图从传输消息中提取逻辑消息 ee5c8703-f509-40aa-a187-a6ce00a7fd1e ---> System.Exception: 不能 查找“Newtonsoft.Json.Linq.JObject”的元数据。\u000d\u000aEnsure 以下内容:\u000d\u000a1。 'Newtonsoft.Json.Linq.JObject' 是 包含在初始扫描中。 \u000d\u000a2。 “Newtonsoft.Json.Linq.JObject”实现“IMessage”、“IEvent” 或“ICommand”,或者,如果您不想实现 界面,您可以使用“不显眼模式”。\u000d\u000a at NServiceBus.Unicast.Messages.MessageMetadataRegistry.GetMessageMetadata(类型 messageType) 在 ...
// 将序列化程序设置为 NewtonSoftSerializer 它似乎 是相同的错误“NServiceBus.ExceptionInfo.StackTrace”: “NServiceBus.MessageDeserializationException:发生错误时 试图从传输消息中提取逻辑消息 603e07e7-7877-4d71-90b3-a6ce00a9370b ---> System.Exception: 不能 查找“Newtonsoft.Json.Linq.JObject”的元数据。\u000d\u000aEnsure 以下内容:\u000d\u000a1。 'Newtonsoft.Json.Linq.JObject' 是 包含在初始扫描中。 \u000d\u000a2。 “Newtonsoft.Json.Linq.JObject”实现“IMessage”、“IEvent” 或“ICommand”,或者,如果您不想实现 界面,您可以使用“不显眼模式”。\u000d\u000a at NServiceBus.Unicast.Messages.MessageMetadataRegistry.GetMessageMetadata(类型 messageType) 在 ...
这感觉就像几件事情中的一件或全部。根据我所看到的,我的想法是:
- 由于某种原因,当我设置 json 序列化程序时,对象正在使用相同的方法进行序列化(不确定是什么)
- 无论我设置什么序列化程序(或者即使我通过向反序列化程序添加相同的序列化程序来进行镜像),它都会尝试使用 Newtonsoft 对其进行反序列化
我认为可能有用的其他点:
- 来自消息中包含的标头(来自错误队列):
- 当我使用任一 json 序列化程序时,内容类型为 application/json,内部异常为 Newtonsoft.Json.JsonReaderException
- 不设置序列化器时,内容类型为text/xml,内部异常为Newtonsoft.Json.JsonReaderException
- 这是托管在 WebAPI 应用程序中
- 也许这会影响序列化程序的选择?
- 消息类位于共享 pcl 库中。我没有实现 IMessage (etc) 接口,而是在配置期间将它们包含在约定中(不显眼的模式)。
- 这有一段时间工作正常,然后本周才开始抛出这些错误。我找不到任何与 NServiceBus 相关的更改。
- 我曾经在使用命令时遇到过这个问题,但是当我为 NServiceBus 添加 Newtonsoft nuget 库时,命令 (Send()) 停止抛出此错误。但是现在事件 (Publish()) 仍然抛出相同的异常
- 我在另一个线程中看到,有人建议查看消息中的 json 正文,以查看序列化的正文是否具有 $type 属性。它不是。
任何见解都会有所帮助。为什么序列化器不排队?
这里有一些杂项:
配置:
public static void Initialize(
string endpointName,
string instanceDescriminator,
IWindsorContainer container)
{
_endpointConfiguration = new EndpointConfiguration(ServiceEndpoint.Surveys);
_endpointConfiguration.SendFailedMessagesTo("error");
_endpointConfiguration.MakeInstanceUniquelyAddressable(instanceDescriminator);
_endpointConfiguration.UseContainer<WindsorBuilder>(customizations =>
{
customizations.ExistingContainer(container);
});
_endpointConfiguration.UsePersistence<NHibernatePersistence, StorageType.Sagas>();
_endpointConfiguration.UsePersistence<NHibernatePersistence, StorageType.Subscriptions>();
_endpointConfiguration.UsePersistence<NHibernatePersistence, StorageType.Timeouts>();
_endpointConfiguration.UsePersistence<NHibernatePersistence, StorageType.Outbox>();
_endpointConfiguration.UsePersistence<NHibernatePersistence, StorageType.GatewayDeduplication>();
_endpointConfiguration.EnableOutbox();
_endpointConfiguration.UseTransport<SqlServerTransport>();
_endpointConfiguration.EnableInstallers();
NServiceBusConventions.SetDasConventions(_endpointConfiguration);
}
约定:
public static void SetDasConventions(EndpointConfiguration config)
{
var conventions = config.Conventions();
conventions.DefiningCommandsAs(type => type.Namespace != null && type.Namespace.StartsWith("DAS.Infrastructure.Messaging.Command"));
conventions.DefiningEventsAs(type => type.Namespace != null && type.Namespace.StartsWith("DAS.Infrastructure.Messaging.Event"));
conventions.DefiningMessagesAs(type =>
type.Namespace != null &&
(type.Namespace.StartsWith("DAS.Infrastructure.Messaging.Message") || type.Namespace.StartsWith("DAS.Infrastructure.Messaging")));
conventions.DefiningEncryptedPropertiesAs(property => property.Name.StartsWith("Encrypted"));
conventions.DefiningDataBusPropertiesAs(property => property.Name.EndsWith("DataBus"));
conventions.DefiningExpressMessagesAs(type => type.Name.EndsWith("Express"));
conventions.DefiningTimeToBeReceivedAs(type => type.Name.EndsWith("Expires") ? TimeSpan.FromSeconds(30) : TimeSpan.MaxValue);
}
【问题讨论】:
-
能把代码分享到github/dropbox吗?
标签: c# serialization nservicebus