45

I have this Queue Trigger. The expected is when I insert a message in the Queue, the trigger must fire and process the dequeued message.

    [FunctionName("NewPayrollQueueTrigger")]
    public async static void Run([QueueTrigger("myqueue", Connection = 
    "AzureWebJobsStorage")]string myQueueItem,
        [DurableClient] IDurableOrchestrationClient starter,
        ILogger log)
    {
        log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");

        await starter.StartNewAsync("NewPayrollOrchestrator", input: myQueueItem);

    }

The trigger is being activated normally, but this weird behavior is happening. The function apparently expects that the message is encoded in Base-64.

Exception binding parameter 'myQueueItem' <--- The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.

I'm sending messages to the queue using this method from the Azure Queue library v.12 from Azure.Storage.Queues and found no overloads that encodes the message to Base-64. Note that _queue is a QueueClient instance.

 public async Task<Response<SendReceipt>> SendAsync(string message)
 {
        return await _queue.SendMessageAsync(message);
 }

So I tried to encode the message by myself...

 public async Task<Response<SendReceipt>> SendAsBase64Async(string message)
 {
      byte[] buffer = Encoding.Unicode.GetBytes(message);
      string msg = Convert.ToBase64String(buffer);

      return await _queue.SendMessageAsync(msg);

 }

... and it doesn't work either. Here's my code passing by that part but throwing error further on, indicating that it could get the message but it was not decoded correctly, since it was a filename of an existing blob in a storage:

Decode error

The only way to get this working is if I manually send a message to the queue using the Azure Storage Explorerchoosing for encode the message via UI.

2
  • what's the message that you're trying to enqueue? Commented Jul 21, 2020 at 21:40
  • the one in question was raw20200721061429372.pdf Commented Jul 21, 2020 at 21:43

3 Answers 3

88

As an alternative, you can take advantage of the built in functionality for converting the message to Base64 by creating the client with an QueueClientOptions with MessageEncoding set to QueueMessageEncoding.Base64.

For example:

_queue = new QueueClient(connectionString, queueName, new QueueClientOptions
{
    MessageEncoding = QueueMessageEncoding.Base64
});

...

var message = "some message";
await _queue.SendMessageAsync(message); // Will be converted as Base64.
Sign up to request clarification or add additional context in comments.

6 Comments

This is what worked for me and I believe should be the correct answer.
This is a good solution and a workaround to shortcoming at Microsoft. Come on Microsoft... If you use QueueClient.SendMessageAsync or QueueClient.RecieveMessageAsync they don't use any encoding. Thus, I would expect Microsoft to allow the QueueTrigger to use no encoding (i.e. UTF8) by default. Default (Send) should work with default (Receive) should work with default (QueueTrigger). This is poor design of the library.
I'm not sure if I'm missing something obvious here, but I've created a QueueClient with a QueueClientOptions object with the MessageEncoding as suggested here, but when I call SendMessageAsync my message is not being encoded in Base64. The only difference is that I am converting an object to JSON first, assuming that the JSON would then be encoded in Base64.
Why does this happen in the first place? This answer worked for one of them (yay), but i've got another queue in the same project, same azure storage etc, doing almost the same thing, and it works without specifying the QueueMessageEncoding? Crazy.
Was this option removed?
The option is still there.
14

Use Azure.Storage.Queues nuget package and use the following code to convert string to Base 64 encode. You need to encode using Encoding.UTF8.GetBytes (plainText).

await queueClient.SendMessageAsync(Base64Encode(serializedCommand), cancellationToken);

private static string Base64Encode(string plainText)
{
    var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
    return System.Convert.ToBase64String(plainTextBytes);
}

For more details, you could refer to this issue.

3 Comments

I am using Azure.Storage.Queues as I described, _queue is an instance of QueueClient as shows in the docs. I'm actually doing exactly what you posted, please, look at the third code block in the question.
Oh, I found my mistake. Can you emphasize in your answer that you need to encode using Encoding.UTF8.GetBytes (plainText) and not Encoding.Unicode.GetBytes (plainText) as I did first? It must be encoded in UTF-8 format! Now it's working!
@RamonDias you should switch the accepted answer to the one below from Johan Classon. It is the correct way from the SDK itself.
13

If you're using version 5.0.0 or higher of Microsoft.Azure.WebJobs.Extensions.Storage, you can set the message encoding in host.json:

{
    "version": "2.0",
    "extensions": {
        "queues": {
            "messageEncoding": "none"
        }
    }
}

https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-queue#hostjson-settings

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.