Question

I have a process that creates SQS messages and places them on an SQS queue and another process that reads those messages and performs certain logic based on the contents of the body and attributes of the message.

I can successfully create a message on the SQS queue with body and attributes, but I have a problem when reading the message attributes back!

I am sure my message creation process is correct, I can see the attributes in the AWS SQS console for the queue. I just cannot figure out why I cannot read those attributes back.

My code to create the message:

IAmazonSQS sqs = AWSClientFactory.CreateAmazonSQSClient();
var sendMessageRequest = new SendMessageRequest();
sendMessageRequest.QueueUrl = "myURL";
Dictionary<string, MessageAttributeValue> MessageAttributes = new Dictionary<string, MessageAttributeValue>();
MessageAttributeValue messageTypeAttribute = new MessageAttributeValue();
messageTypeAttribute.DataType = "String";
messageTypeAttribute.StringValue = "HIGH";
MessageAttributes.Add("MESSAGEPRIORITY", messageTypeAttribute);

sendMessageRequest.MessageAttributes = MessageAttributes;
sendMessageRequest.MessageBody = "Thats the message body";

sqs.SendMessage(sendMessageRequest);

The above works and a message with attribute MESSAGEPRIORITY=HIGH is created (I can see the message and attribute in the SQS Console).

When reading back the message (I've skipped parts of the code that show Queue URL etc):

IAmazonSQS sqs = AWSClientFactory.CreateAmazonSQSClient();
ReceiveMessageResponse receiveMessage = new ReceiveMessageResponse();
ReceiveMessageRequest request = new ReceiveMessageRequest();
request.QueueUrl = "myURL";
receiveMessage = sqs.ReceiveMessage(request);
string messageBody = receiveMessage.Messages[0].Body;
Dictionary<string, MessageAttributeValue> messageAttributes = receiveMessage.Messages[0].MessageAttributes;

With the above code, I get the body of the message, but the attributes are empty! I have the same problem when creating the message manually using the SQS queue directly. I can't figure out why? Any help would be great. Many thanks,

Was it helpful?

Solution

Ok so I figured this one out. The attribute names need to be specified as a property of the ReceiveMessageRequest object before the call is made to pull the message.

So, the code above needs to change to:

IAmazonSQS sqs = AWSClientFactory.CreateAmazonSQSClient();
ReceiveMessageResponse receiveMessage = new ReceiveMessageResponse();
ReceiveMessageRequest request = new ReceiveMessageRequest();

//Specify attribute list
List<string> AttributesList = new List<string>();
AttributesList.Add("MESSAGEPRIORITY");

//Assign list and QueueURL to request
request.MessageAttributeNames = AttributesList;
request.QueueUrl = "myURL";

//Receive the message...
receiveMessage = sqs.ReceiveMessage(request);
//Body...
string messageBody = receiveMessage.Messages[0].Body;
//...and attributes
Dictionary<string, MessageAttributeValue> messageAttributes = receiveMessage.Messages[0].MessageAttributes;

The above works for me. Hopefully it'll be useful to someone....

OTHER TIPS

To retrieve all attributes of a message without specifying each one you can put "*" or "All" in your attributes list. Like so :

//Specify attribute list
List<string> AttributesList = new List<string>();
AttributesList.Add("*");

AWS SQS ReceiveMessage documentation

a complete method to read from SQS

    public async Task ReadFromSQS()
    {
        IAmazonSQS sqs = new AmazonSQSClient(RegionEndpoint.EUWest1);
        try
        {
            List<string> AttributesList = new List<string>();
            AttributesList.Add("NameOfTheAttribute");

            ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest();
            receiveMessageRequest.QueueUrl = IdQueue;
            receiveMessageRequest.MessageAttributeNames = AttributesList;
            ReceiveMessageResponse receiveMessageResponse = await sqs.ReceiveMessageAsync(receiveMessageRequest);

            foreach (Message message in receiveMessageResponse.Messages)
            {
                Debug.WriteLine("Body: "+ message.Body);
                Debug.WriteLine("Values: " + message.MessageAttributes.Count);
                foreach (var entry in message.MessageAttributes)
                {
                    Debug.WriteLine("Attribute");
                    Debug.WriteLine("Name: "+ entry.Key);
                    Debug.WriteLine("Value1: "+ entry.Value.StringValue);
                }
            }
            String messageRecieptHandle = receiveMessageResponse.Messages[0].ReceiptHandle;
            //Deleting a message
            Debug.WriteLine("Deleting the message.\n");
            DeleteMessageRequest deleteRequest = new DeleteMessageRequest();
            deleteRequest.QueueUrl = IdQueue;
            deleteRequest.ReceiptHandle = messageRecieptHandle;
            await sqs.DeleteMessageAsync(deleteRequest);
        }
        catch (AmazonSQSException ex)
        {
            Debug.WriteLine("Caught Exception: " + ex.Message);
            Debug.WriteLine("Response Status Code: " + ex.StatusCode);
            Debug.WriteLine("Error Code: " + ex.ErrorCode);
            Debug.WriteLine("Error Type: " + ex.ErrorType);
            Debug.WriteLine("Request ID: " + ex.RequestId);
        }

        Debug.WriteLine("Press Enter to continue...");
        Console.Read();
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top