best practice for function app service bus trigger and blobinput attribute

Wang Meihua 135 Reputation points
2024-10-28T07:07:06.75+00:00

this is our function declaration:

User's image

stack error details:

Error converting 1 input parameters for Function 'DistributeBusinessPartner': Cannot convert input parameter 'messageIn' to type 'Azure.Messaging.ServiceBus.ServiceBusReceivedMessage' from type 'System.String'. Error:System.NotSupportedException: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'Azure.Messaging.ServiceBus.ServiceBusReceivedMessage'. Path: $ | LineNumber: 0 | BytePositionInLine: 1.

then based on the error message, we fixed the issue by changing the function declaration like below:

User's image

but if we change messageIn to string type, meesageIn will only receive the message body instead of the ServiceBusReceivedMessage object, we wanted to confirm if there's a way to let us use ServiceBusReceivedMessage and BlobInput correctly at the same time, or what's the best practice of this case? thank you very much.

https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-service-bus-trigger?tabs=python-v2%2Cisolated-process%2Cnodejs-v4%2Cextensionv5&pivots=programming-language-csharp#example

Azure Functions
Azure Functions
An Azure service that provides an event-driven serverless compute platform.
5,909 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Pinaki Ghatak 5,600 Reputation points Microsoft Employee Volunteer Moderator
    2024-10-28T10:34:25.4566667+00:00

    Hello @Wang Meihua

    The error message suggests that the ServiceBusReceivedMessage object does not have a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with JsonConstructorAttribute, which is required for deserialization.

    To use ServiceBusReceivedMessage and BlobInput correctly at the same time, you can modify your function declaration to include both parameters, like this:

    public static void Run( [ServiceBusTrigger("myqueue")]
    ServiceBusReceivedMessage messageIn, [Blob("mycontainer/{MessageId}", FileAccess.Read)] Stream myBlob)
    { 
    	// Your code here 
    }
    

    This will allow you to receive both the ServiceBusReceivedMessage object and the blob input in your function. You can then use the properties of the ServiceBusReceivedMessage object to process the message, and the contents of the blob to perform any necessary operations. Alternatively, you can also modify your function to receive the message body as a string, and then use the ServiceBusReceivedMessage constructor to create a new instance of the object, like this:

    public static void Run( [ServiceBusTrigger("myqueue")] string messageBody, [Blob("mycontainer/{MessageId}", FileAccess.Read)] Stream myBlob)
    { 
    	ServiceBusReceivedMessage messageIn = new
     		ServiceBusReceivedMessage(Encoding.UTF8.GetBytes(messageBody));
    	// Your code here
     }
    

    This will allow you to receive the message body as a string, and then create a new instance of the ServiceBusReceivedMessage object using the constructor that takes a byte array.


    I hope that this response has addressed your query and helped you overcome your challenges. If so, please mark this response as Answered. This will not only acknowledge our efforts, but also assist other community members who may be looking for similar solutions.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.