Recently we started updating an Azure Functions project that processes dead letter
messages from EventGrid that couldn’t be delivered to our Azure Storage Queues. As
part of the upgrade we migrated from the deprecated Microsoft.Azure.EventGrid
library to the Azure.Messaging.EventGrid
library and came across a few differences
that required somce changes to our code.
Getting the EventGridEvents from the blob trigger
Previously, we used the Newtonsoft.JSON
library to deserialize the data passed
to the blob trigger as follows:
1[FunctionName("DeadLetterProcessing")]
2public void Run(
3 [BlobTrigger(_blobPath, Connection = _conn)] string myBlob,
4 string name,
5 ILogger log)
6{
7 EventGridEvent[] _events = JsonConvert.DeserializeObject<EventGridEvent>(myBlob);
8
9 // etc.
10}
However, using the new library the EventGridEvent
type no longer has a default
constructor that allows you to deserialize the JSON data directly. Instead, you
need to use static methods on the EventGridEvent
type to process the data as
follows:
EventGridEvent.Parse()
for a single eventEventGridEvent.ParseMany()
for multiple events
When processing dead letter events from EventGrid, it will always be an array
of at least 1 event, so we will need to use the ParseManu()
method.
We will also need to use the static methods on the BinaryData
type to process
the data received by the blob trigger into a BinaryData
type.:
BinaryData.FromString()
if you used thestring
binding option on the blob triggerBinaryData.FromStream()
if you used theStream
binding option on the blo trigger
1[FunctionName("DeadLetterProcessing")]
2public void Run(
3 [BlobTrigger(_blobPath, Connection = _conn)]Stream myBlob,
4 string name,
5 ILogger log)
6{
7 EventGridEvent[] _events = EventGridEvent.ParseMany(BinaryData.FromStream(myBlob));
8}
Getting the custom data from the EventGridEvent.Data
property
The next issue we encountered is trying to deserialize the custom data stored in
the Data
property of the EventGridEvent
. Again, we used to just deserialize
the Data
property directly but this is no longer an object type, but rather a
BinaryData
type.
This means that we need to use the .ToObjectFromJson<T>()
method of the
BinaryData
type to process the custom data property into our custom data object.
1EventGridEvent[] _events = EventGridEvent.ParseMany(BinaryData.FromString(myBlob));
2
3foreach (EventGridEvent eventGridEvent in _events)
4{
5 CustomEventGridData data = eventGridEvent.Data.ToObjectFromJson<CustomEventGridData>();
6
7 // use you data as needed
8}
Of particular note, the new library makes use of System.Text.Json
to serialize
the custom data. This means that you need to switch to using the JsonPropertyName
attribute on your data classes in order to deserialize the data properly.
Hence our custom data object need to be updated as follows:
1using System.Text.Json.Serialization;
2
3public class CustomEventGridData
4{
5 [JsonPropertyName("orderNumber")]
6 public int OrderNumber { get; set; }
7
8 [JsonPropertyName("orderTotal")]
9 public int OrderTotal { get; set; }
10}
Wrap up
None of this was hard, but we needed to pay closer attention to the changes
described in Migration Guide that was
linked from the deprecation notice on the old Microsoft.Azure.EventGrid
library.
However, the portion that applied to our situation was a couple of small paragraphs
near the end of the document while the rest seemed more focused on the support
for the CloudEvent
type from Azure.Core
… a standardized event type from the
Cloud Native Computing Foundation.
Details of the specification can be found at cloudevents.io.
Hopefully this helps someone else switching to the new library find what they are looking for quicker!