Microsoft.Azure.ServiceBus.Message cannot be used as Azure Function return type on .NET 6.0?

Viewed 889

I have just upgraded my Azure Functions from .NET Core 3.1 to .NET 6.0, the Azure Functions runtime from v3 to v4, and upgraded all package references accordingly to the latest version, including:

  • Microsoft.NET.Sdk.Functions 4.0.1
  • Microsoft.Azure.Functions.Extensions 1.1.0
  • Microsoft.Azure.WebJobs.Extensions.ServiceBus 5.1.0
  • Microsoft.Azure.ServiceBus 5.2.0

A number of my functions have now started erroring. A simple reproducible example is below:

public class MyTimerFunction
{
    [FunctionName(nameof(MyTimerFunction))]
    [return: ServiceBus("MyQueue", Connection = "ServiceBusConnectionString")]
    public Message Run(
        [TimerTrigger("0 * * * * *")] TimerInfo timer,   // Runs every 1 minute
        CancellationToken cancellationToken)
    {
        var bytes = Encoding.UTF8.GetBytes("Hello world!");
        var message = new Message(bytes) { SessionId = "MySession" };
        return message;
    }
}

This is the error I get:

System.Private.CoreLib: Exception while executing function: MyTimerFunction. Microsoft.Azure.WebJobs.Host: Error while handling parameter $return after function returned:. Newtonsoft.Json: Error getting value from 'ExpiresAtUtc' on 'Microsoft.Azure.ServiceBus.Message'. Microsoft.Azure.ServiceBus: Operation is not valid due to the current state of the object.

Something seems to have been broken in the binding of the Message return type. I need to use Message (rather than return the payload directly) because of the SessionId. The latest documentation from Microsoft still uses this Message class: Azure Service Bus output binding for Azure Functions.

I'm aware that a new Azure.Messaging.ServiceBus library has been released to replace Microsoft.Azure.ServiceBus, but I would prefer to get this issue fixed on the old library first.

1 Answers

I uncovered the answer a bit further down the Azure Service Bus output binding for Azure Functions documentation:

Apps using the 5.0.0 or higher version of the Service Bus extension use the ServiceBusMessage type in Azure.Messaging.ServiceBus instead of the one in the Microsoft.Azure.ServiceBus namespace. This version drops support for the legacy Message type in favor of the following types: ServiceBusMessage

In this case, "Service Bus extension" refers to Microsoft.Azure.WebJobs.Extensions.ServiceBus, which itself references Azure.Messaging.ServiceBus. Thus, my function is already using this new library indirectly. The solution is to change the return type from Message to ServiceBusMessage:

using Azure.Messaging.ServiceBus;   // new namespace
…

public class MyTimerFunction
{
    [FunctionName(nameof(MyTimerFunction))]
    [return: ServiceBus("MyQueue", Connection = "ServiceBusConnectionString")]
    public ServiceBusMessage Run(
        [TimerTrigger("0 * * * * *")] TimerInfo timer)   // Runs every 1 minute
    {
        var bytes = Encoding.UTF8.GetBytes("Hello world!");
        var message = new Message(bytes) { SessionId = "MySession" };
        return message;
    }
}
Related