I have migrated an Azure function from .NET 6 in-process to .NET 8 isolated. After the migration, everything works fine except EventData
. I have a timer function which sends an array of EventData
as output binding to event hub.
This is my code - this is the event hub output binding model:
using System.Diagnostics.CodeAnalysis;
using Azure.Messaging.EventHubs;
using Microsoft.Azure.Functions.Worker;
public class RetryFailedEventHubOutputBindings
{
public RetryFailedEventHubOutputBindings()
{
OutEventHub1 = [];
OutEventHub2 = [];
}
[EventHubOutput("OutEventHub1", Connection = "EventHubConnection")]
public EventData[] OutEventHub1 { get; set; }
[EventHubOutput("OutEventHub2", Connection = "EventHubConnection")]
public EventData[] OutEventHub2 { get; set; }
}
This is my TimeTrigger
function (sender):
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Azure.Messaging.EventHubs;
using Microsoft.Azure.Functions.Worker;
using Newtonsoft.Json;
public class RetryFailedFunction
{
private static readonly SemaphoreSlim Semaphore = new(1, 1);
private readonly IFailedMessageService _failedMessageService;
private readonly IAppLogger<RetryFailedPlayerEventFunction> _logger;
public RetryFailedFunction(IFailedMessageService failedMessageService, IAppLogger<RetryFailedPlayerEventFunction> logger)
{
_failedMessageService = failedMessageService;
_logger = logger;
}
[Function(nameof(RetryFailedFunction))]
public async Task<RetryFailedEventHubOutputBindings> RunAsync([TimerTrigger("%ScheduleTriggerTime%")] TimerInfo myTimer)
{
var outputBindings = new RetryFailedEventHubOutputBindings();
outputBindings.EventHub2.Append(new EventData(Encoding.UTF8.GetBytes("{\"ErrorId\": 10}")));
return outputBindings;
}
}
This is the event hub trigger function (receiver):
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Text;
using System.Threading.Tasks;
using Azure.Messaging.EventHubs;
using Microsoft.Azure.Functions.Worker;
using Newtonsoft.Json;
public class ReceiverFunction
{
private readonly IErrorRepository _errRepo;
private readonly IRawEventHandler _rawEventHandler;
private readonly IProductValidationHelper _productValidationHelper;
private readonly IAppLogger<GenPlayerEventFromDepositsFunction> _logger;
private readonly IUpdateRetryStatusService _updateRetryStatusService;
public ReceiverFunction(IErrorRepository errRepo, IUpdateRetryStatusService updateRetryStatusService, IRawEventHandler rawEventHandler, IProductValidationHelper productValidationHelper, IAppLogger<GenPlayerEventFromDepositsFunction> logger)
{
_errRepo = errRepo;
_updateRetryStatusService = updateRetryStatusService;
_rawEventHandler = rawEventHandler;
_productValidationHelper = productValidationHelper;
_logger = logger;
}
[Function(nameof(ReceiverFunction))]
[EventHubOutput("SomeEventHub", Connection = "EventHubConnection_1")]
public async Task<string[]> RunAsync([EventHubTrigger("EventHub2", Connection = "EventHubConnection", ConsumerGroup = "%EventHubConsumerGroup%")] EventData[] inputEvents)
{
var outputEvents = new List<string>();
foreach (var eventData in inputEvents)
{
// Event processing logic
}
}
}
This is what I see in output, instead of actual data it's showing just datatype in output:
These are changes in my package of function app after migration:
As shown in first image, I'm not receiving expected data in receiver event hub, instead it's just showing data type.
If I change then data type to any other type like string[]
or string
or any other strongly type, then it's working without any issues, problem is only for EventData
, either it's EventData
array or just EventData
.
And EventData[]
was also working in old code, before migration.
Can you please help me with this issue, is there any limitation with .NET 8 isolated Azure function for EventData
, or am I doing something wrong here?
Yes, Indeed EventData[] or EventData
type is not yet supported in EventHub output binding for isolated worker model.
You can refer to the isolated output binding usage doc which says while writing a single event, event hub output binding can bind to string, byte[], JSON serializable types in isolated function.
Whereas for in-process model output binding, it supports Azure.Messaging.EventHubs.EventData, string, byte[], - Plain-old CLR object (POCO) types.
As you have correctly identified by changing the type to string or any other type apart from EventData, it works in isolated worker model.
I have the below given code which works for me.
public class RetryFailedEventHubOutputBindings
{
public RetryFailedEventHubOutputBindings()
{
OutEventHub1 = [];
OutEventHub2 = [];
}
[EventHubOutput("OutEventHub1", Connection = "EventHubConnection")]
public string[] OutEventHub1 { get; set; }
[EventHubOutput("OutEventHub2", Connection = "EventHubConnection")]
public string[] OutEventHub2 { get; set; }
}
Sender function :-
[Function("RetryFailedFunction")]
public async Task<RetryFailedEventHubOutputBindings> Run([TimerTrigger("0 */2 * * * *")] TimerInfo myTimer)
{
var outputBindings = new RetryFailedEventHubOutputBindings
{
OutEventHub2 = new[] { JsonConvert.SerializeObject(new { ErrorId = 10 }) }
};
return outputBindings;
}
Receiver function :-
[Function(nameof(ReceiverFunction))]
public void Run([EventHubTrigger("OutEventHub2", Connection = "EventHubConnection")] EventData[] events)
{
foreach (EventData @event in events)
{
_logger.LogInformation("Event Body: {body}", @event.EventBody);
}
}
Response :-
Azure Functions Core Tools
Core Tools Version: 4.0.6821 Commit hash: N/A +c09a2033faa7ecf51b3773308283af0ca9a99f83 (64-bit)
Function Runtime Version: 4.1036.1.23224
[2025-01-16T05:41:40.732Z] Found C:\Users\*****\79358853\79358853\79358853.csproj. Using for user secrets file configuration.
[2025-01-16T05:41:43.559Z] Azure Functions .NET Worker (PID: 15628) initialized in debug mode. Waiting for debugger to attach...
[2025-01-16T05:41:43.595Z] Worker process started and initialized.
Functions:
ReceiverFunction: eventHubTrigger
RetryFailedFunction: timerTrigger
For detailed output, run func with --verbose flag.
[2025-01-16T05:41:43.877Z] Executing 'Functions.RetryFailedFunction' (Reason='Timer fired at 2025-01-16T11:11:43.8573126+05:30', Id=e21ae124-c14b-4b04-9296-718971f04fe2)
[2025-01-16T05:41:43.879Z] Trigger Details: UnscheduledInvocationReason: IsPastDue, OriginalSchedule: 2025-01-16T10:58:00.0000000+05:30
[2025-01-16T05:41:46.900Z] Executed 'Functions.RetryFailedFunction' (Succeeded, Id=e21ae124-c14b-4b04-9296-718971f04fe2, Duration=3038ms)
[2025-01-16T05:41:48.456Z] Executing 'Functions.ReceiverFunction' (Reason='(null)', Id=4921187d-8ffe-43e0-a839-b44229ef83fa)
[2025-01-16T05:41:48.457Z] Trigger Details: PartionId: 0, Offset: 640-640, EnqueueTimeUtc: 2025-01-16T05:41:46.8190000+00:00-2025-01-16T05:41:46.8190000+00:00, SequenceNumber: 8-8, Count: 1
[2025-01-16T05:41:48.523Z] Event Body: {"ErrorId":10}
[2025-01-16T05:41:48.524Z] Executed 'Functions.ReceiverFunction' (Succeeded, Id=4921187d-8ffe-43e0-a839-b44229ef83fa, Duration=81ms)