Jonas Stensved
Jonas Stensved

Reputation: 15276

Azure Function .NET5 (isolated) throws when using [EventGridTrigger] EventGridEvent as parameter

After upgrade to .NET5 for Azure Function this signature throws the exception below.

I've implemented it according to the documentation here https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-event-grid-trigger?tabs=csharp%2Cbash

 [Function(nameof(CustomerCreated))]
 public async Task CustomerCreated([EventGridTrigger] EventGridEvent eventGridEvent, FunctionContext functionContext)
 {

   // My implementation

 }

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.EventGrid.EventGridEvent'. Path: $ | LineNumber: 0 | BytePositionInLine: 1.'

How can I receive the event from EventGrid?

Upvotes: 5

Views: 2015

Answers (1)

Jonas Stensved
Jonas Stensved

Reputation: 15276

The new way of doing this seems to be CloudEvent from the Azure.Messaging namespace.

(A side note is that the data properties are case-sensitive, I'm not sure if they were before.)

public async Task CustomerCreated([EventGridTrigger] CloudEvent eventGridEvent, FunctionContext functionContext)
{
     // [...]
}

UPDATE:

This breaks when deploying to Azure and receiving events from a real event grid with an Azure Function as endpoints. But works fine when testing locally using ngrok and webhook. Back to square one.

After endless googling with outdated examples I found a note in this document, pointing to this example showing that you need to create a custom type (looking just like the EventGridEvent).

After testing I found that this actually works:

Pass a string instead of EventGridEvent and parse the actual event with the utility function from EventGridEvent.

[Function(nameof(CustomerCreated))]
public async Task CustomerCreated([EventGridTrigger] string data, FunctionContext functionContext)
{
    var eventGridEvent = EventGridEvent.Parse(BinaryData.FromString(data));
    
    // Rest of code
}

Another related caveat is that you can't create the function from the portal but need to run it from the command line like:

az eventgrid event-subscription create --name customer-created \
    --source-resource-id <event-grid-topic-resource-id> \
    --endpoint <azure-func-resource-id> --endpoint-type azurefunction

(The resource id:s can be found at http://resources.azure.com/)

Hello Microsoft;

Running Azure Functions on .NET5 doesn't feel very GA with this approach. I really hope to be able to pass typed objects like EventGridEvent from other Azure services with official libraries.

I really think that the EventGridEvent on .NET5/dotnet-isolated should be compatible with Azure Functions at the same level as on previous .NET versions and as in the public examples.

Upvotes: 13

Related Questions