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
Install
npx skills add https://github.com/microsoft/skills/tree/main/.github/plugins/azure-sdk-dotnet/skills/azure-eventgrid-dotnet
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install microsoft-skills@llmmart
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
- Use CloudEvents — Prefer CloudEvents for new implementations (industry standard)
- Batch events — Send multiple events in one call for efficiency
- Use Entra ID — Prefer managed identity over access keys
- Idempotent handlers — Events may be delivered more than once
- Set event TTL — Configure time-to-live for namespace events
- Handle partial failures — Acknowledge/release events individually
- Use dead-letter — Configure dead-letter for failed events
- 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
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.
Reviews (0)
No reviews yet.
No comments yet.