10

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.

Ramon Dias
  • 372
  • 1
  • 4
  • 14

3 Answers3

17

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.
Johan Classon
  • 481
  • 5
  • 6
  • 1
    This is what worked for me and I believe should be the correct answer. – Xenophage Feb 05 '21 at 17:21
  • this is a better solution than marked. thank you – Ivan Doroshenko Mar 09 '21 at 16:02
  • 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. – KarlZ Apr 02 '21 at 20:31
11

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.

Joey Cai
  • 15,590
  • 1
  • 7
  • 19
  • I am using `Azure.Storage.Queues` as I described, `_queue` is an instance of [QueueClient](https://docs.microsoft.com/en-us/dotnet/api/azure.storage.queues.queueclient.-ctor?view=azure-dotnet) as shows in the [docs](https://docs.microsoft.com/pt-br/azure/storage/queues/storage-dotnet-how-to-use-queues?tabs=dotnet#create-a-queue). I'm actually doing **exactly** what you posted, please, look at the third code block in the question. – Ramon Dias Jul 22 '20 at 14:17
  • 1
    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! – Ramon Dias Jul 22 '20 at 14:32
  • @RamonDias you should switch the accepted answer to the one below from Johan Classon. It is the correct way from the SDK itself. – J Flex Mar 29 '21 at 08:23
0

You are using the old nuget package version. Upgrade to Azure.Storage.Queue and it should work as expected

Thiago Custodio
  • 13,761
  • 6
  • 36
  • 74
  • I am using `Azure.Storage.Queues` as I described, `_queue` is an instance of [QueueClient](https://docs.microsoft.com/en-us/dotnet/api/azure.storage.queues.queueclient.-ctor?view=azure-dotnet) as shows in the [docs](https://docs.microsoft.com/pt-br/azure/storage/queues/storage-dotnet-how-to-use-queues?tabs=dotnet#create-a-queue). – Ramon Dias Jul 22 '20 at 14:11