New to Claude Skills? Learn how to install them →

sickn33 on GitHub

Azure Event Grid SDK

Free

Publish and consume events with Azure Event Grid in .NET.

Get this skill

Free · Opens the source repo

What Azure Event Grid SDK does

The Azure Event Grid SDK for .NET provides a robust client library designed for developers looking to implement event-driven architectures using Azure Event Grid. This library allows you to publish and consume events efficiently, enabling seamless integration with Azure's event routing capabilities. It supports both push and pull delivery models, making it versatile for various application needs.

With the SDK, you can easily send events to Azure Event Grid topics and domains, or utilize namespaces for pull delivery. The library supports the CloudEvents specification, allowing for interoperability with other event-driven systems. Developers can choose between different authentication methods, including API key, Microsoft Entra ID, and SAS token, ensuring secure access to the Event Grid service.

The SDK's client hierarchy includes specialized clients for publishing events, such as the EventGridPublisherClient for push delivery and EventGridSenderClient for pull delivery. This structure simplifies the process of sending single or batch events, whether they are standard EventGridEvents or CloudEvents. Additionally, the SDK allows for custom serialization options, providing flexibility in how event data is formatted.

This skill is ideal for .NET developers who are looking to enhance their applications with event-driven capabilities, enabling them to respond to events in real-time and build scalable, reactive systems.

When to use it

Use this skill when you need to implement event publishing and consumption in .NET applications, particularly when leveraging Azure's event routing features.

When not to use it

This skill may not be suitable for applications that do not require event-driven architecture or for developers not working within the .NET ecosystem.

What you can build with it

Publishing Order Events

Use the SDK to publish order-related events to Azure Event Grid when an order is created or updated.

Receiving Events in Real-Time

Implement a system that receives and processes events from Azure Event Grid using the pull delivery model.

Integrating with CloudEvents

Utilize the SDK to send CloudEvents for interoperability with other event-driven systems.

How to install Azure Event Grid SDK

View source

1. Install with the skills CLI

npx skills add sickn33/agentic-awesome-skills/azure-eventgrid-dotnet --agent claude-code

2. Or install it manually

Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.

Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs

Inside SKILL.md

Written by sickn33

Azure.Messaging.EventGrid (.NET)

Client library for publishing events to Azure Event Grid topics, domains, and namespaces.

Installation

# For topics and domains (push delivery)
dotnet add package Azure.Messaging.EventGrid

# For namespaces (pull delivery)
dotnet add package Azure.Messaging.EventGrid.Namespaces

# For CloudNative CloudEvents interop
dotnet add package Microsoft.Azure.Messaging.EventGrid.CloudNativeCloudEvents

Current Version: 4.28.0 (stable)

Environment Variables

# Topic/Domain endpoint
EVENT_GRID_TOPIC_ENDPOINT=https://<topic-name>.<region>.eventgrid.azure.net/api/events
EVENT_GRID_TOPIC_KEY=<access-key>

# Namespace endpoint (for pull delivery)
EVENT_GRID_NAMESPACE_ENDPOINT=https://<namespace>.<region>.eventgrid.azure.net
EVENT_GRID_TOPIC_NAME=<topic-name>
EVENT_GRID_SUBSCRIPTION_NAME=<subscription-name>

Client Hierarchy

Push Delivery (Topics/Domains)
└── EventGridPublisherClient
    ├── SendEventAsync(EventGridEvent)
    ├── SendEventsAsync(IEnumerable<EventGridEvent>)
    ├── SendEventAsync(CloudEvent)
    └── SendEventsAsync(IEnumerable<CloudEvent>)

Pull Delivery (Namespaces)
├── EventGridSenderClient
│   └── SendAsync(CloudEvent)
└── EventGridReceiverClient
    ├── ReceiveAsync()
    ├── AcknowledgeAsync()
    ├── ReleaseAsync()
    └── RejectAsync()

Authentication

API Key Authentication

using Azure;
using Azure.Messaging.EventGrid;

EventGridPublisherClient client = new(
    new Uri("https://mytopic.eastus-1.eventgrid.azure.net/api/events"),
    new AzureKeyCredential("<access-key>"));

Microsoft Entra ID (Recommended)

using Azure.Identity;
using Azure.Messaging.EventGrid;

EventGridPublisherClient client = new(
    new Uri("https://mytopic.eastus-1.eventgrid.azure.net/api/events"),
    new DefaultAzureCredential());

SAS Token Authentication

string sasToken = EventGridPublisherClient.BuildSharedAccessSignature(
    new Uri(topicEndpoint),
    DateTimeOffset.UtcNow.AddHours(1),
    new AzureKeyCredential(topicKey));

var sasCredential = new AzureSasCredential(sasToken);
EventGridPublisherClient client = new(
    new Uri(topicEndpoint),
    sasCredential);

Publishing Events

EventGridEvent Schema

EventGridPublisherClient client = new(
    new Uri(topicEndpoint),
    new AzureKeyCredential(topicKey));

// Single event
EventGridEvent egEvent = new(
    subject: "orders/12345",
    eventType: "Order.Created",
    dataVersion: "1.0",
    data: new { OrderId = "12345", Amount = 99.99 });

await client.SendEventAsync(egEvent);

// Batch of events
List<EventGridEvent> events = new()
{
    new EventGridEvent(
        subject: "orders/12345",
        eventType: "Order.Created",
        dataVersion: "1.0",
        data: new OrderData { OrderId = "12345", Amount = 99.99 }),
    new EventGridEvent(
        subject: "orders/12346",
        eventType: "Order.Created",
        dataVersion: "1.0",
        data: new OrderData { OrderId = "12346", Amount = 149.99 })
};

await client.SendEventsAsync(events);

CloudEvent Schema

CloudEvent cloudEvent = new(
    source: "/orders/system",
    type: "Order.Created",
    data: new { OrderId = "12345", Amount = 99.99 });

cloudEvent.Subject = "orders/12345";
cloudEvent.Id = Guid.NewGuid().ToString();
cloudEvent.Time = DateTimeOffset.UtcNow;

await client.SendEventAsync(cloudEvent);

// Batch of CloudEvents
List<CloudEvent> cloudEvents = new()
{
    new CloudEvent("/orders", "Order.Created", new { OrderId = "1" }),
    new CloudEvent("/orders", "Order.Updated", new { OrderId = "2" })
};

await client.SendEventsAsync(cloudEvents);

Publishing to Event Grid Domain

// Events must specify the Topic property for domain routing
List<EventGridEvent> events = new()
{
    new EventGridEvent(
        subject: "orders/12345",
        eventType: "Order.Created",
        dataVersion: "1.0",
        data: new { OrderId = "12345" })
    {
        Topic = "orders-topic"  // Domain topic name
    },
    new EventGridEvent(
        subject: "inventory/item-1",
        eventType: "Inventory.Updated",
        dataVersion: "1.0",
        data: new { ItemId = "item-1" })
    {
        Topic = "inventory-topic"
    }
};

await client.SendEventsAsync(events);

Custom Serialization

using System.Text.Json;

var serializerOptions = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};

var customSerializer = new JsonObjectSerializer(serializerOptions);

EventGridEvent egEvent = new(
    subject: "orders/12345",
    eventType: "Order.Created",
    dataVersion: "1.0",
    data: customSerializer.Serialize(new OrderData { OrderId = "12345" }));

await client.SendEventAsync(egEvent);

Pull Delivery (Namespaces)

Send Events to Namespace Topic

using Azure;
using Azure.Messaging;
using Azure.Messaging.EventGrid.Namespaces;

var senderClient = new EventGridSenderClient(
    new Uri(namespaceEndpoint),
    topicName,
    new AzureKeyCredential(topicKey));

// Send single event
CloudEvent cloudEvent = new("employee_source", "Employee.Created", 
    new { Name = "John", Age = 30 });
await senderClient.SendAsync(cloudEvent);

// Send batch
await senderClient.SendAsync(new[]
{
    new CloudEvent("source", "type", new { Name = "Alice" }),
    new CloudEvent("source", "type", new { Name = "Bob" })
});

Receive and Process Events

var receiverClient = new EventGridReceiverClient(
    new Uri(namespaceEndpoint),
    topicName,
    subscriptionName,
    new AzureKeyCredential(topicKey));

// Receive events
ReceiveResult result = await receiverClient.ReceiveAsync(maxEvents: 10);

List<string> lockTokensToAck = new();
List<string> lockTokensToRelease = new();

foreach (ReceiveDetails detail in result.Details)
{
    CloudEvent cloudEvent = detail.Event;
    string lockToken = detail.BrokerProperties.LockToken;
    
    try
    {
        // Process the event
        Console.WriteLine($"Event: {cloudEvent.Type}, Data: {cloudEvent.Data}");
        lockTokensToAck.Add(lockToken);
    }
    catch (Exception)
    {
        // Release for retry
        lockTokensToRelease.Add(lockToken);
    }
}

// Acknowledge successfully processed events
if (lockTokensToAck.Any())
{
    await receiverClient.AcknowledgeAsync(lockTokensToAck);
}

// Release events for retry
if (lockTokensToRelease.Any())
{
    await receiverClient.ReleaseAsync(lockTokensToRelease);
}

Reject Events (Dead Letter)

// Reject events that cannot be processed
await receiverClient.RejectAsync(new[] { lockToken });

Consuming Events (Azure Functions)

EventGridEvent Trigger

using Azure.Messaging.EventGrid;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.EventGrid;

public static class EventGridFunction
{
    [FunctionName("ProcessEventGridEvent")]
    public static void Run(
        [EventGridTrigger] EventGridEvent eventGridEvent,
        ILogger log)
    {
        log.LogInformation($"Event Type: {eventGridEvent.EventType}");
        log.LogInformation($"Subject: {eventGridEvent.Subject}");
        log.LogInformation($"Data: {eventGridEvent.Data}");
    }
}

CloudEvent Trigger

using Azure.Messaging;
using Microsoft.Azure.Functions.Worker;

public class CloudEventFunction
{
    [Function("ProcessCloudEvent")]
    public void Run(
        [EventGridTrigger] CloudEvent cloudEvent,
        FunctionContext context)
    {
        var logger = context.GetLogger("ProcessCloudEvent");
        logger.LogInformation($"Event Type: {cloudEvent.Type}");
        logger.LogInformation($"Source: {cloudEvent.Source}");
        logger.LogInformation($"Data: {cloudEvent.Data}");
    }
}

Parsing Events

Parse EventGridEvent

// From JSON string
string json = "..."; // Event Grid webhook payload
EventGridEvent[] events = EventGridEvent.ParseMany(BinaryData.FromString(json));

foreach (EventGridEvent egEvent in events)
{
    if (egEvent.TryGetSystemEventData(out object systemEvent))
    {
        // Handle system event
        switch (systemEvent)
        {
            case StorageBlobCreatedEventData blobCreated:
                Console.WriteLine($"Blob created: {blobCreated.Url}");
                break;
        }
    }
    else
    {
        // Handle custom event
        var customData = egEvent.Data.ToObjectFromJson<MyCustomData>();
    }
}

Parse CloudEvent

CloudEvent[] cloudEvents = CloudEvent.ParseMany(BinaryData.FromString(json));

foreach (CloudEvent cloudEvent in cloudEvents)
{
    var data = cloudEvent.Data.ToObjectFromJson<MyEventData>();
    Console.WriteLine($"Type: {cloudEvent.Type}, Data: {data}");
}

System Events

// Common system event types
using Azure.Messaging.EventGrid.SystemEvents;

// Storage events
StorageBlobCreatedEventData blobCreated;
StorageBlobDeletedEventData blobDeleted;

// Resource events
ResourceWriteSuccessEventData resourceCreated;
ResourceDeleteSuccessEventData resourceDeleted;

// App Service events
WebAppUpdatedEventData webAppUpdated;

// Container Registry events
ContainerRegistryImagePushedEventData imagePushed;

// IoT Hub events
IotHubDeviceCreatedEventData deviceCreated;

Key Types Reference

TypePurpose
EventGridPublisherClientPublish to topics/domains
EventGridSenderClientSend to namespace topics
EventGridReceiverClientReceive from namespace subscriptions
EventGridEventEvent Grid native schema
CloudEventCloudEvents 1.0 schema
ReceiveResultPull delivery response
ReceiveDetailsEvent with broker properties
BrokerPropertiesLock token, delivery count

Event Schemas Comparison

FeatureEventGridEventCloudEvent
StandardAzure-specificCNCF standard
Required fieldssubject, eventType, dataVersion, datasource, type
ExtensibilityLimitedExtension attributes
InteroperabilityAzure onlyCross-platform

Best Practices

  1. Use CloudEvents — Prefer CloudEvents for new implementations (industry standard)
  2. Batch events — Send multiple events in one call for efficiency
  3. Use Entra ID — Prefer managed identity over access keys
  4. Idempotent handlers — Events may be delivered more than once
  5. Set event TTL — Configure time-to-live for namespace events
  6. Handle partial failures — Acknowledge/release events individually
  7. Use dead-letter — Configure dead-letter for failed events
  8. Validate schemas — Validate event data before processing

Error Handling

using Azure;

try
{
    await client.SendEventAsync(cloudEvent);
}
catch (RequestFailedException ex) when (ex.Status == 401)
{
    Console.WriteLine("Authentication failed - check credentials");
}
catch (RequestFailedException ex) when (ex.Status == 403)
{
    Console.WriteLine("Authorization failed - check RBAC permissions");
}
catch (RequestFailedException ex) when (ex.Status == 413)
{
    Console.WriteLine("Payload too large - max 1MB per event, 1MB total batch");
}
catch (RequestFailedException ex)
{
    Console.WriteLine($"Event Grid error: {ex.Status} - {ex.Message}");
}

Failover Pattern

try
{
    var primaryClient = new EventGridPublisherClient(primaryUri, primaryKey);
    await primaryClient.SendEventsAsync(events);
}
catch (RequestFailedException)
{
    // Failover to secondary region
    var secondaryClient = new EventGridPublisherClient(secondaryUri, secondaryKey);
    await secondaryClient.SendEventsAsync(events);
}

Related SDKs

SDKPurposeInstall
Azure.Messaging.EventGridTopics/Domains (this SDK)dotnet add package Azure.Messaging.EventGrid
Azure.Messaging.EventGrid.NamespacesPull deliverydotnet add package Azure.Messaging.EventGrid.Namespaces
Azure.IdentityAuthenticationdotnet add package Azure.Identity
Microsoft.Azure.WebJobs.Extensions.EventGridAzure Functions triggerdotnet add package Microsoft.Azure.WebJobs.Extensions.EventGrid

Reference Links

ResourceURL
NuGet Packagehttps://www.nuget.org/packages/Azure.Messaging.EventGrid
API Referencehttps://learn.microsoft.com/dotnet/api/azure.messaging.eventgrid
Quickstarthttps://learn.microsoft.com/azure/event-grid/custom-event-quickstart
Pull Deliveryhttps://learn.microsoft.com/azure/event-grid/pull-delivery-overview
GitHub Sourcehttps://github.com/Azure/azure-sdk-for-net/tree/main/sdk/eventgrid/Azure.Messaging.EventGrid

When to Use

This skill is applicable to execute the workflow or actions described in the overview.

Limitations

  • Use this skill only when the task clearly matches the scope described above.
  • Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
  • Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.

Frequently asked questions about Azure Event Grid SDK

Similar skills