.net core 2.2 host failing to deserialize .net framework 4.5 sent NServicebus Message

Hey There,

We creating a .net core 2.2 nservicebus host and am sending a message to the host from a .net framework nservicebus host and are getting a deserialization exception. Below is the stack trace we are getting from the .net core host

NServiceBus.MessageDeserializationException: An error occurred while attempting to extract logical messages from incoming physical message a9146186-28e3-458e-be9f-aa150101e091 ---> System.Exception: Could not find metadata for 'Newtonsoft.Json.Linq.JObject'.
Ensure the following:
1. 'Newtonsoft.Json.Linq.JObject' is included in initial scanning.
2. 'Newtonsoft.Json.Linq.JObject' implements either 'IMessage', 'IEvent' or 'ICommand' or alternatively, if you don't want to implement an interface, you can use 'Unobtrusive Mode'.
  at NServiceBus.Unicast.Messages.MessageMetadataRegistry.GetMessageMetadata(Type messageType) in C:\BuildAgent\work\ed946b9f0e4aae01\src\NServiceBus.Core\Unicast\Messages\MessageMetadataRegistry.cs:line 26
  at NServiceBus.Pipeline.LogicalMessageFactory.Create(Type messageType, Object message) in C:\BuildAgent\work\ed946b9f0e4aae01\src\NServiceBus.Core\Pipeline\Incoming\LogicalMessageFactory.cs:line 51
  at NServiceBus.DeserializeLogicalMessagesConnector.Extract(IncomingMessage physicalMessage) in C:\BuildAgent\work\ed946b9f0e4aae01\src\NServiceBus.Core\Pipeline\Incoming\DeserializeLogicalMessagesConnector.cs:line 123
  at NServiceBus.DeserializeLogicalMessagesConnector.ExtractWithExceptionHandling(IncomingMessage message) in C:\BuildAgent\work\ed946b9f0e4aae01\src\NServiceBus.Core\Pipeline\Incoming\DeserializeLogicalMessagesConnector.cs:line 47
  --- End of inner exception stack trace ---
  at NServiceBus.DeserializeLogicalMessagesConnector.ExtractWithExceptionHandling(IncomingMessage message) in C:\BuildAgent\work\ed946b9f0e4aae01\src\NServiceBus.Core\Pipeline\Incoming\DeserializeLogicalMessagesConnector.cs:line 51
  at NServiceBus.DeserializeLogicalMessagesConnector.Invoke(IIncomingPhysicalMessageContext context, Func`2 stage) in C:\BuildAgent\work\ed946b9f0e4aae01\src\NServiceBus.Core\Pipeline\Incoming\DeserializeLogicalMessagesConnector.cs:line 31
  at NServiceBus.UnitOfWorkBehavior.InvokeUnitsOfWork(IIncomingPhysicalMessageContext context, Func`2 next) in C:\BuildAgent\work\ed946b9f0e4aae01\src\NServiceBus.Core\UnitOfWork\UnitOfWorkBehavior.cs:line 40
  at NServiceBus.MutateIncomingTransportMessageBehavior.InvokeIncomingTransportMessagesMutators(IIncomingPhysicalMessageContext context, Func`2 next) in C:\BuildAgent\work\ed946b9f0e4aae01\src\NServiceBus.Core\MessageMutators\MutateTransportMessage\MutateIncomingTransportMessageBehavior.cs:line 59
  at NServiceBus.InvokeAuditPipelineBehavior.Invoke(IIncomingPhysicalMessageContext context, Func`2 next) in C:\BuildAgent\work\ed946b9f0e4aae01\src\NServiceBus.Core\Audit\InvokeAuditPipelineBehavior.cs:line 20
  at NServiceBus.ProcessingStatisticsBehavior.Invoke(IIncomingPhysicalMessageContext context, Func`2 next) in C:\BuildAgent\work\ed946b9f0e4aae01\src\NServiceBus.Core\Performance\Statistics\ProcessingStatisticsBehavior.cs:line 25
  at NServiceBus.TransportReceiveToPhysicalMessageProcessingConnector.Invoke(ITransportReceiveContext context, Func`2 next) in C:\BuildAgent\work\ed946b9f0e4aae01\src\NServiceBus.Core\Pipeline\Incoming\TransportReceiveToPhysicalMessageProcessingConnector.cs:line 39
  at NServiceBus.MainPipelineExecutor.Invoke(MessageContext messageContext) in C:\BuildAgent\work\ed946b9f0e4aae01\src\NServiceBus.Core\Pipeline\MainPipelineExecutor.cs:line 34

.NET Core 2.2 host Package Versions

7.1.6 - NServiceBus
2.2.0 - NServiceBus.Newtonsoft.Json
5.0.2 - NServiceBus.RabbitMQ

.Net Framework host Package Versions

5.2.14 - NServiceBus
2.0.5 - NServiceBus.RabbitMQ

Message Assembly Package Versions

5.2.14 - NServiceBus

Thanks!

So more information. If we change the .net core 2.2 host to .net framework 4.7.1 the message deserialization works fine. Therefore there seems to be some bug/backwards incompatibility when using the above package versions and a .net framework endpoint talking to a .net core endpoint.

Hey @lochness

If your message assembly package targets NServiceBus version 5, it will only target .NET Framework. This could explain why the app works when targeting .NET Framework 4.7 as it can load the message assembly but not when running on .NET Core, as it would require the messages assembly to either target .NET Core or .NET Standard to be able to load it.

if you look at the diagnostics file in your .diagnostics folder besides your binaries you should be able to see whether the endpoint was able to load the messages assembly or not. Maybe you can share that file with us to have a look at (the diagnostics file is only written when using NServiceBus v7).

Hey Tim,

I just want to be clear.

The assembly contract is .net framework using nservicebus v5 as a dependency since we are not using conventions.

When we send a message from .net framework host => .net core host the deserialization error happens

When we send a message from .net core host => .net core host it deserializes and works fine

To follow up on what lochness said, it doesn’t appear to be an issue with loading the assembly. I can see the v5 assembly being loaded by the .net core host in the debug output (and the .diagnostics file) and the correct handler being associated to it.

I have attempted to reproduce the issue, but I’m not yet seeing a problem.

Based on my understanding of your scenario, here is what I’m doing:

I have an NServiceBus 5 endpoint that sends a command and an NServiceBus 7 endpoint that receives the command. Both are using JSON serialization. There is a shared message project that is using NServiceBus 5 that both endpoints reference.

I have tried running the NServiceBus 7 endpoint on both net472 and netcoreapp2.2, and the NSB7 endpoint is able to process the message without a problem on both.

Does my repro attempt replicate your scenario correctly?

What does the message you’re having a problem with look like? Can you share the code for it?

Yes that sounds similar. The only difference is the message project is a nuget package and we are publishing an event. One thing we were worried about is that the nsb 7 host is using the NewtonsoftSerializer and the nsb 5 host is using the old json serializer. Here is the message

public class SalesOrderCancelled : ISalesOrderCancelled
{
    public int SiteId { get; set; }
    public Guid CorrelationId { get; set; }
}

public interface ISalesOrderCancelled : IOrderCancelled { }

public interface IOrderCancelled : IEvent
{
    int SiteId { get; set; }
    Guid CorrelationId { get; set; }
}

I’ve updated my repro to use your message types and tried a variety of scenarios with it, and I still cannot see a failure.

Can you share your entire repro code? There must be something specific to your code that I’m missing. If you don’t want to share it publicly, please open a support case mentioning me, and we can look at it in more detail there.

Hey Brandon,

One thing i noticed we are doing is publishing a concrete type instead of an interface.

Are we able to get a call going? I will send a email to support@particular.net and include this thread since we have a enterprise license through particular.

Hi, me too face the similar issue. Have you got the solution for this issue? And how?

Hey @Rajan_Al,

The issue was related to the assembly version used for the message contracts. If the publisher uses a higher assembly version than the consumer this was happening.

Thank you. My case is different. Consumer is .net core with nservicebus 7. But the publisher is .net framework 4.* Having reference with nservicebus 5.

So, I decided to decouple the publisher by removing the nservicebus dependency.