Search code examples
c#.netjsonrabbitmqnservicebus

NServiceBus Handler throwing metadata errors


After updating NServiceBus to the latest version released last week (which also has a new implementation), I'm seeing weird errors when sending json from the client.

I will send a message from the client and the receiver displays this message:

2016-10-18 22:16:33.612 INFO MFG.Receiver.DeviceHandler Got message with id: a222b136-6a4e-474e-8012-cc1c24e5e539

I have a breakpoint in my handler, below, and it shows the message object is baked and there should not be any issues.

public class DeviceHandler : IHandleMessages<DeviceRequest>
{
    private readonly IDeviceProvider _provider = new DeviceProvider();
    private static readonly ILog Log = LogManager.GetLogger<DeviceHandler>();

    public Task Handle(DeviceRequest message, IMessageHandlerContext context)
    {
        Log.Info($"Got message with id: {context.MessageId}");
        ...
        return context.SendLocal($"Message with Id {context.MessageId} received.");
    }
}

When it hits the reply method at the end, it throws the below errors:

2016-10-18 22:16:33.666 INFO NServiceBus.RecoverabilityExecutor Immediate Retry is going to retry message 'a222b136-6a4e-474e-8012-cc1c24e5e539' because of an exception: System.Exception: Could not find metadata for 'System.String'. Ensure the following: 1. 'System.String' is included in initial scanning. 2. 'System.String' 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:\Build\src\NServiceBus.Core\Unicast\Messages\MessageMetadataRegistry.cs:line 39

I'm not sure why it would throw the System.String error, after it already received the message from the handler and the properties are populated...

The json sent looks like this:

{
  "$type": "DeviceRequest, MFG.Domain",
  "Id": "devices-65",
  "DeviceId": 1,
  "Location": "Orlando",
  "DeviceType": "test"
}

My Sender (client) looks like this:

static void Main()
{
    ...
        using (var channel = connection.CreateModel())
        {
            var messageId = Guid.NewGuid().ToString();
            var properties = channel.CreateBasicProperties();
            properties.MessageId = messageId;

            var payload = GenerateJsonPayload();

            channel.BasicPublish(string.Empty, ServerEndpointName, false, properties, Encoding.UTF8.GetBytes(payload));
            Console.WriteLine($"Message with id {messageId} sent to queue.");
        }
     ...
}

public static string GenerateJsonPayload()
{
    var obj = new DeviceRequest
    {
        DeviceId = 1,
        DeviceType = "test",
        Location = "Orlando"
    };

    var settings = new JsonSerializerSettings
    {
        TypeNameHandling = TypeNameHandling.All
    };

    var result = JsonConvert.SerializeObject(obj, Formatting.Indented, settings);

    return result;
}

I've had the "could not find metadata" issue before, and it was due to malformed json or not having type. If I remove the JsonSerializerSettings, and just passed a serialized object, I instead get errors:

2016-10-18 22:31:27.698 ERROR NServiceBus.RecoverabilityExecutor Moving message '6405179d-ea36-4264-af2a-704da19af120' to the error queue 'error' because processing failed due to an exception: NServiceBus.MessageDeserializationException: An error occurred while attempting to extract logical messages from transport message 6405179d-ea36-4264-af2a-704da19af120 ---> System.Exception: Could not find metadata for 'Newtonsoft.Json.Linq.JObject'.

I have no idea what I'm missing here and this wasn't an issue with the previous version. Is this a bug or ... ?


Solution

  • Use a concrete message type for your SendLocal operation.

    As part of handling the message you are doing return context.SendLocal($"Message with Id {context.MessageId} received.");. This will try to send a message of type "string" to the local queue. NServiceBus is telling you that no message metadata was registered for the message type of "string". Therefor it can not construct the message and throws an exception.