azure-eventgrid-dotnet

npx skills add https://github.com/microsoft/skills --skill azure-eventgrid-dotnet

Azure.Messaging.EventGrid (.NET)

Bibliothèque cliente pour publier des événements vers les rubriques, domaines et namespaces Azure Event Grid.

Installation

# Pour les rubriques et domaines (livraison push)
dotnet add package Azure.Messaging.EventGrid

# Pour les namespaces (livraison pull)
dotnet add package Azure.Messaging.EventGrid.Namespaces

# Pour l'interopérabilité CloudNative CloudEvents
dotnet add package Microsoft.Azure.Messaging.EventGrid.CloudNativeCloudEvents

Version actuelle : 4.28.0 (stable)

Variables d'environnement

# Point de terminaison rubrique/domaine
EVENT_GRID_TOPIC_ENDPOINT=https://<topic-name>.<region>.eventgrid.azure.net/api/events
EVENT_GRID_TOPIC_KEY=<access-key>

# Point de terminaison namespace (pour la livraison pull)
EVENT_GRID_NAMESPACE_ENDPOINT=https://<namespace>.<region>.eventgrid.azure.net
EVENT_GRID_TOPIC_NAME=<topic-name>
EVENT_GRID_SUBSCRIPTION_NAME=<subscription-name>

Hiérarchie des clients

Livraison push (rubriques/domaines)
└── EventGridPublisherClient
    ├── SendEventAsync(EventGridEvent)
    ├── SendEventsAsync(IEnumerable<EventGridEvent>)
    ├── SendEventAsync(CloudEvent)
    └── SendEventsAsync(IEnumerable<CloudEvent>)

Livraison pull (namespaces)
├── EventGridSenderClient
│   └── SendAsync(CloudEvent)
└── EventGridReceiverClient
    ├── ReceiveAsync()
    ├── AcknowledgeAsync()
    ├── ReleaseAsync()
    └── RejectAsync()

Authentification

Authentification par clé API

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 (recommandé)

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

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

Authentification par jeton SAS

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);

Publication d'événements

Schéma EventGridEvent

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

// Événement unique
EventGridEvent egEvent = new(
    subject: "orders/12345",
    eventType: "Order.Created",
    dataVersion: "1.0",
    data: new { OrderId = "12345", Amount = 99.99 });

await client.SendEventAsync(egEvent);

// Lot d'événements
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);

Schéma CloudEvent

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);

// Lot de 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);

Publication vers un domaine Event Grid

// Les événements doivent spécifier la propriété Topic pour le routage du domaine
List<EventGridEvent> events = new()
{
    new EventGridEvent(
        subject: "orders/12345",
        eventType: "Order.Created",
        dataVersion: "1.0",
        data: new { OrderId = "12345" })
    {
        Topic = "orders-topic"  // Nom de la rubrique du domaine
    },
    new EventGridEvent(
        subject: "inventory/item-1",
        eventType: "Inventory.Updated",
        dataVersion: "1.0",
        data: new { ItemId = "item-1" })
    {
        Topic = "inventory-topic"
    }
};

await client.SendEventsAsync(events);

Sérialisation personnalisée

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);

Livraison pull (namespaces)

Envoyer des événements vers une rubrique namespace

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

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

// Envoyer un événement unique
CloudEvent cloudEvent = new("employee_source", "Employee.Created", 
    new { Name = "John", Age = 30 });
await senderClient.SendAsync(cloudEvent);

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

Recevoir et traiter les événements

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

// Recevoir les événements
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
    {
        // Traiter l'événement
        Console.WriteLine($"Event: {cloudEvent.Type}, Data: {cloudEvent.Data}");
        lockTokensToAck.Add(lockToken);
    }
    catch (Exception)
    {
        // Libérer pour réessai
        lockTokensToRelease.Add(lockToken);
    }
}

// Confirmer les événements traités avec succès
if (lockTokensToAck.Any())
{
    await receiverClient.AcknowledgeAsync(lockTokensToAck);
}

// Libérer les événements pour réessai
if (lockTokensToRelease.Any())
{
    await receiverClient.ReleaseAsync(lockTokensToRelease);
}

Rejeter les événements (Dead Letter)

// Rejeter les événements qui ne peuvent pas être traités
await receiverClient.RejectAsync(new[] { lockToken });

Consommer les événements (Azure Functions)

Déclencheur EventGridEvent

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}");
    }
}

Déclencheur CloudEvent

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}");
    }
}

Analyser les événements

Analyser EventGridEvent

// À partir d'une chaîne JSON
string json = "..."; // Charge utile webhook Event Grid
EventGridEvent[] events = EventGridEvent.ParseMany(BinaryData.FromString(json));

foreach (EventGridEvent egEvent in events)
{
    if (egEvent.TryGetSystemEventData(out object systemEvent))
    {
        // Gérer l'événement système
        switch (systemEvent)
        {
            case StorageBlobCreatedEventData blobCreated:
                Console.WriteLine($"Blob created: {blobCreated.Url}");
                break;
        }
    }
    else
    {
        // Gérer l'événement personnalisé
        var customData = egEvent.Data.ToObjectFromJson<MyCustomData>();
    }
}

Analyser 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}");
}

Événements système

// Types d'événements système courants
using Azure.Messaging.EventGrid.SystemEvents;

// Événements de stockage
StorageBlobCreatedEventData blobCreated;
StorageBlobDeletedEventData blobDeleted;

// Événements de ressources
ResourceWriteSuccessEventData resourceCreated;
ResourceDeleteSuccessEventData resourceDeleted;

// Événements App Service
WebAppUpdatedEventData webAppUpdated;

// Événements Container Registry
ContainerRegistryImagePushedEventData imagePushed;

// Événements IoT Hub
IotHubDeviceCreatedEventData deviceCreated;

Référence des types clés

Type Objectif
EventGridPublisherClient Publier vers les rubriques/domaines
EventGridSenderClient Envoyer vers les rubriques namespace
EventGridReceiverClient Recevoir depuis les abonnements namespace
EventGridEvent Schéma natif Event Grid
CloudEvent Schéma CloudEvents 1.0
ReceiveResult Réponse de livraison pull
ReceiveDetails Événement avec propriétés du courtier
BrokerProperties Jeton de verrouillage, nombre de livraisons

Comparaison des schémas d'événement

Fonctionnalité EventGridEvent CloudEvent
Standard Spécifique à Azure Standard CNCF
Champs obligatoires subject, eventType, dataVersion, data source, type
Extensibilité Limitée Attributs d'extension
Interopérabilité Azure uniquement Inter-plateformes

Bonnes pratiques

  1. Utiliser CloudEvents — Préférer CloudEvents pour les nouvelles implémentations (standard du secteur)
  2. Regrouper les événements — Envoyer plusieurs événements en un seul appel pour l'efficacité
  3. Utiliser Entra ID — Préférer l'identité managée aux clés d'accès
  4. Gestionnaires idempotents — Les événements peuvent être livrés plus d'une fois
  5. Définir un TTL d'événement — Configurer le time-to-live pour les événements namespace
  6. Gérer les défaillances partielles — Confirmer/libérer les événements individuellement
  7. Utiliser la dead-letter — Configurer la dead-letter pour les événements échoués
  8. Valider les schémas — Valider les données d'événement avant le traitement

Gestion des erreurs

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}");
}

Schéma de basculement

try
{
    var primaryClient = new EventGridPublisherClient(primaryUri, primaryKey);
    await primaryClient.SendEventsAsync(events);
}
catch (RequestFailedException)
{
    // Basculer vers la région secondaire
    var secondaryClient = new EventGridPublisherClient(secondaryUri, secondaryKey);
    await secondaryClient.SendEventsAsync(events);
}

SDKs connexes

SDK Objectif Installation
Azure.Messaging.EventGrid Rubriques/domaines (ce SDK) dotnet add package Azure.Messaging.EventGrid
Azure.Messaging.EventGrid.Namespaces Livraison pull dotnet add package Azure.Messaging.EventGrid.Namespaces
Azure.Identity Authentification dotnet add package Azure.Identity
Microsoft.Azure.WebJobs.Extensions.EventGrid Déclencheur Azure Functions dotnet add package Microsoft.Azure.WebJobs.Extensions.EventGrid

Liens de référence

Ressource URL
Package NuGet https://www.nuget.org/packages/Azure.Messaging.EventGrid
Référence API https://learn.microsoft.com/dotnet/api/azure.messaging.eventgrid
Démarrage rapide https://learn.microsoft.com/azure/event-grid/custom-event-quickstart
Livraison pull https://learn.microsoft.com/azure/event-grid/pull-delivery-overview
Source GitHub https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/eventgrid/Azure.Messaging.EventGrid

Skills similaires