GitHub Copilot ChatGPT Claude Codex CLI Cursor opencode Skill Text

azure-eventgrid-dotnet

Azure Event Grid SDK for .NET. Client library for publishing and consuming events with Azure Event Grid. Use for event-driven architectures, pub/sub messaging, CloudEvents, and EventGridEvents. Triggers: "Event Grid", "EventGridPublisherClient", "CloudEvent", "EventGridEvent", "p

Ciza · 0 points · 23 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download microsoft-skills-.github_plugins_azure-sdk-dotnet_skills_azure-eventgrid-dotnet-e58528d.zip · 4 KB
Part of microsoft/skills — 195 skills

Install

skills CLI npx skills add https://github.com/microsoft/skills/tree/main/.github/plugins/azure-sdk-dotnet/skills/azure-eventgrid-dotnet
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install microsoft-skills@llmmart
Git git clone https://github.com/microsoft/skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole microsoft/skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

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

EVENT_GRID_TOPIC_ENDPOINT=https://<topic-name>.<region>.eventgrid.azure.net/api/events  # Required: Event Grid topic or domain endpoint
EVENT_GRID_TOPIC_KEY=<access-key>  # Only required for AzureKeyCredential auth
EVENT_GRID_NAMESPACE_ENDPOINT=https://<namespace>.<region>.eventgrid.azure.net  # Optional: Event Grid namespace endpoint
EVENT_GRID_TOPIC_NAME=<topic-name>  # Required: Event Grid topic name
EVENT_GRID_SUBSCRIPTION_NAME=<subscription-name>  # Optional: Event Grid subscription name
AZURE_TOKEN_CREDENTIALS=prod  # Required only if DefaultAzureCredential is used in production

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 Token Credential

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

// Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential>
var credential = new DefaultAzureCredential(
    DefaultAzureCredential.DefaultEnvironmentVariableName
);
// Or use a specific credential directly in production:
// See https://learn.microsoft.com/dotnet/api/overview/azure/identity-readme?view=azure-dotnet#credential-classes
// var credential = new ManagedIdentityCredential();
EventGridPublisherClient client = new(
    new Uri("https://mytopic.eastus-1.eventgrid.azure.net/api/events"),
    credential);

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

Type Purpose
EventGridPublisherClient Publish to topics/domains
EventGridSenderClient Send to namespace topics
EventGridReceiverClient Receive from namespace subscriptions
EventGridEvent Event Grid native schema
CloudEvent CloudEvents 1.0 schema
ReceiveResult Pull delivery response
ReceiveDetails Event with broker properties
BrokerProperties Lock token, delivery count

Event Schemas Comparison

Feature EventGridEvent CloudEvent
Standard Azure-specific CNCF standard
Required fields subject, eventType, dataVersion, data source, type
Extensibility Limited Extension attributes
Interoperability Azure only Cross-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

SDK Purpose Install
Azure.Messaging.EventGrid Topics/Domains (this SDK) dotnet add package Azure.Messaging.EventGrid
Azure.Messaging.EventGrid.Namespaces Pull delivery dotnet add package Azure.Messaging.EventGrid.Namespaces
Azure.Identity Authentication dotnet add package Azure.Identity
Microsoft.Azure.WebJobs.Extensions.EventGrid Azure Functions trigger dotnet add package Microsoft.Azure.WebJobs.Extensions.EventGrid

Reference Links

Resource URL
NuGet Package https://www.nuget.org/packages/Azure.Messaging.EventGrid
API Reference https://learn.microsoft.com/dotnet/api/azure.messaging.eventgrid
Quickstart https://learn.microsoft.com/azure/event-grid/custom-event-quickstart
Pull Delivery https://learn.microsoft.com/azure/event-grid/pull-delivery-overview
GitHub Source https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/eventgrid/Azure.Messaging.EventGrid
Files (skills)
  • SKILL.md 13.7 KB
    ---
    name: azure-eventgrid-dotnet
    description: |
      Azure Event Grid SDK for .NET. Client library for publishing and consuming events with Azure Event Grid. Use for event-driven architectures, pub/sub messaging, CloudEvents, and EventGridEvents. Triggers: "Event Grid", "EventGridPublisherClient", "CloudEvent", "EventGridEvent", "publish events .NET", "event-driven", "pub/sub".
    license: MIT
    metadata:
      author: Microsoft
      version: "1.0.0"
      package: Azure.Messaging.EventGrid
    ---
    
    # Azure.Messaging.EventGrid (.NET)
    
    Client library for publishing events to Azure Event Grid topics, domains, and namespaces.
    
    ## Installation
    
    ```bash
    # 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
    
    ```bash
    EVENT_GRID_TOPIC_ENDPOINT=https://<topic-name>.<region>.eventgrid.azure.net/api/events  # Required: Event Grid topic or domain endpoint
    EVENT_GRID_TOPIC_KEY=<access-key>  # Only required for AzureKeyCredential auth
    EVENT_GRID_NAMESPACE_ENDPOINT=https://<namespace>.<region>.eventgrid.azure.net  # Optional: Event Grid namespace endpoint
    EVENT_GRID_TOPIC_NAME=<topic-name>  # Required: Event Grid topic name
    EVENT_GRID_SUBSCRIPTION_NAME=<subscription-name>  # Optional: Event Grid subscription name
    AZURE_TOKEN_CREDENTIALS=prod  # Required only if DefaultAzureCredential is used in production
    ```
    
    ## 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
    
    ```csharp
    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 Token Credential
    
    ```csharp
    using Azure.Identity;
    using Azure.Messaging.EventGrid;
    
    // Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential>
    var credential = new DefaultAzureCredential(
        DefaultAzureCredential.DefaultEnvironmentVariableName
    );
    // Or use a specific credential directly in production:
    // See https://learn.microsoft.com/dotnet/api/overview/azure/identity-readme?view=azure-dotnet#credential-classes
    // var credential = new ManagedIdentityCredential();
    EventGridPublisherClient client = new(
        new Uri("https://mytopic.eastus-1.eventgrid.azure.net/api/events"),
        credential);
    ```
    
    ### SAS Token Authentication
    
    ```csharp
    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
    
    ```csharp
    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
    
    ```csharp
    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
    
    ```csharp
    // 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
    
    ```csharp
    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
    
    ```csharp
    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
    
    ```csharp
    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)
    
    ```csharp
    // Reject events that cannot be processed
    await receiverClient.RejectAsync(new[] { lockToken });
    ```
    
    ## Consuming Events (Azure Functions)
    
    ### EventGridEvent Trigger
    
    ```csharp
    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
    
    ```csharp
    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
    
    ```csharp
    // 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
    
    ```csharp
    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
    
    ```csharp
    // 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
    
    | Type | Purpose |
    |------|---------|
    | `EventGridPublisherClient` | Publish to topics/domains |
    | `EventGridSenderClient` | Send to namespace topics |
    | `EventGridReceiverClient` | Receive from namespace subscriptions |
    | `EventGridEvent` | Event Grid native schema |
    | `CloudEvent` | CloudEvents 1.0 schema |
    | `ReceiveResult` | Pull delivery response |
    | `ReceiveDetails` | Event with broker properties |
    | `BrokerProperties` | Lock token, delivery count |
    
    ## Event Schemas Comparison
    
    | Feature | EventGridEvent | CloudEvent |
    |---------|----------------|------------|
    | Standard | Azure-specific | CNCF standard |
    | Required fields | subject, eventType, dataVersion, data | source, type |
    | Extensibility | Limited | Extension attributes |
    | Interoperability | Azure only | Cross-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
    
    ```csharp
    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
    
    ```csharp
    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
    
    | SDK | Purpose | Install |
    |-----|---------|---------|
    | `Azure.Messaging.EventGrid` | Topics/Domains (this SDK) | `dotnet add package Azure.Messaging.EventGrid` |
    | `Azure.Messaging.EventGrid.Namespaces` | Pull delivery | `dotnet add package Azure.Messaging.EventGrid.Namespaces` |
    | `Azure.Identity` | Authentication | `dotnet add package Azure.Identity` |
    | `Microsoft.Azure.WebJobs.Extensions.EventGrid` | Azure Functions trigger | `dotnet add package Microsoft.Azure.WebJobs.Extensions.EventGrid` |
    
    ## Reference Links
    
    | Resource | URL |
    |----------|-----|
    | NuGet Package | https://www.nuget.org/packages/Azure.Messaging.EventGrid |
    | API Reference | https://learn.microsoft.com/dotnet/api/azure.messaging.eventgrid |
    | Quickstart | https://learn.microsoft.com/azure/event-grid/custom-event-quickstart |
    | Pull Delivery | https://learn.microsoft.com/azure/event-grid/pull-delivery-overview |
    | GitHub Source | https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/eventgrid/Azure.Messaging.EventGrid |
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related