rebusrebus-azureservicebus

Rebus: Unable to modify / add new headers with BeforeMessageHandled event


We are using the Rebus framework in our application and we currently have some issues adding additional headers before the messages are handled by our handlers.

In my startup:

        }).Events(e =>
        {
            e.BeforeMessageSent += rebusEventHandler.RebusBeforeMessageSent;
            e.BeforeMessageHandled += rebusEventHandler.RebusBeforeMessageHandled;
        })

Catching the event:

public void RebusBeforeMessageHandled(IBus bus, Dictionary<string, string> headers, object message, IncomingStepContext context, MessageHandledEventHandlerArgs args)
{
    … we are fetching mocking headers here

    foreach (var mockingHeader in mockingHeaders)
    {
        headers.TryAdd(mockingHeader.Key, mockingHeader.Value); // values added here are gone in the next step
    } 
   
    headers["my-test"] = "test"; //added for testing (also not saved)


}

When I look at the messageContext.headers in the next handler, the headers I set in the BeforeMessageHandled event are gone again. The my-test header is also gone. So it seems that the modified headers are not saved.

We also use the BeforeMessageSent event and those headers are saved as expected.

public void RebusBeforeMessageSent(IBus bus, Dictionary<string, string> headers, object message, OutgoingStepContext context)
{

     //…

    var messageIdentity = _mijnIdentityContext.CurrentIdentity;

    var messagingIdentityJson = JsonConvert.SerializeObject(messageIdentity);
    headers.Add("x-mijn -identity", messagingIdentityJson);
}

Am I correct that both events are supposed to allow us to modify (and save) the headers?


Solution

  • The problem is that messageContext.Headers refers to the headers of the transport message, which is the (Dictionary<string, string>, byte[]) tuple as represented by the type TransportMessage that Rebus uses to carry the incoming message.

    During the execution of the incoming message pipeline, the message goes through several steps, and one of them is deserialization, which results in a new copy of the message – the "logical message" – which comes in the form of Message, which is basically a (Dictionary<string, string>, object) tuple.

    The headers of Message can be accessed via messageContext.Message.Headers, so I bet you can find your header there. 🙂