Home > Net >  How should I pass a string value in a RabbitMQ header
How should I pass a string value in a RabbitMQ header

Time:11-08

I am trying to add a string value to a RabbitMQ message.

When I compose the message here is the code:

IBasicProperties props = channel.CreateBasicProperties();
props.ContentType = "text/plain";
props.DeliveryMode = 2;
props.Expiration = "36000000";
props.Headers = new Dictionary<string, object>();
props.Headers.Add("entityId", id);
props.Headers.Add("type", GetMessageType(id));

channel.BasicPublish(exchange: "messages",
    routingKey: "",
    basicProperties: props,
    body: body);

The method GetMessageType returns a string.

I retrieve the message like this:

private void ConsumerOnReceived(object sender, BasicDeliverEventArgs e)
{
    var firstMessage = "PO Received";
    var secondMessage = "Do you want to print a Back Order Fill Report?";
    
    var id = (int) e.BasicProperties.Headers.FirstOrDefault(x => x.Key == "entityId").Value;
    string type;
    try
    {
        type = (string)e.BasicProperties.Headers.FirstOrDefault(x => x.Key == "type").Value;
    }
    catch (Exception exception)
    {
        Console.WriteLine(exception);
        throw;
    }
    
    if (type == "OrderCreated")
    {
        firstMessage = "Sales Order Created";
        secondMessage = "Do you want to print the Order?";
    }
    ...

The first header value (entityId) is retrieved just fine. The second (type) causes an exception.

Exception Message: Message = "Unable to cast object of type 'System.Byte[]' to type 'System.String'."

Do I need to convert the byte array back to a string? Or should I only pass integers?

If I need to convert a byte array back to a string, how do I do that?

CodePudding user response:

I found my answer:

type = System.Text.Encoding.UTF8.GetString((byte[])e.BasicProperties.Headers.FirstOrDefault(x => x.Key == "type").Value);

CodePudding user response:

This is due to an old quirk when the RMQ protocol was updated to 0-9-1 .. basically a wire-level inconsistency was introduced and this behavior allows sending a byte array as well as a string header (both are sent as S long-string type).

See https://github.com/rabbitmq/rabbitmq-dotnet-client/issues/415 for a discussion of why the data type information is lost; the link also includes an approach on how to read string headers.

string json;
//We set this as a string, but deliveries will return a UTF8-encoded byte[]..
if (value.GetType() == typeof(byte[]))
{
  json = Encoding.UTF8.GetString((byte[])value);
}

Of course, that could also mean the original header was a byte array.

  • Related