Azure.Messaging.EventGrid (.NET)
Bibliothèque cliente pour publier des événements sur les rubriques, domaines et espaces de noms Azure Event Grid.
Installation
dotnet add package Azure.Messaging.EventGrid
dotnet add package Azure.Messaging.EventGrid.Namespaces
dotnet add package Microsoft.Azure.Messaging.EventGrid.CloudNativeCloudEvents
Version actuelle : 4.28.0 (stable)
Variables d'environnement
EVENT_GRID_TOPIC_ENDPOINT=https://<topic-name>.<region>.eventgrid.azure.net/api/events
EVENT_GRID_TOPIC_KEY=<access-key>
EVENT_GRID_NAMESPACE_ENDPOINT=https://<namespace>.<region>.eventgrid.azure.net
EVENT_GRID_TOPIC_NAME=<topic-name>
EVENT_GRID_SUBSCRIPTION_NAME=<subscription-name>
AZURE_TOKEN_CREDENTIALS=prod
Hiérarchie des clients
Livraison par poussée (Rubriques/Domaines)
└── EventGridPublisherClient
├── SendEventAsync(EventGridEvent)
├── SendEventsAsync(IEnumerable<EventGridEvent>)
├── SendEventAsync(CloudEvent)
└── SendEventsAsync(IEnumerable<CloudEvent>)
Livraison par tirage (Espaces de noms)
├── 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>"));
Jeton d'identification Microsoft Entra
using Azure.Identity;
using Azure.Messaging.EventGrid;
var credential = new DefaultAzureCredential(
DefaultAzureCredential.DefaultEnvironmentVariableName
);
EventGridPublisherClient client = new(
new Uri("https://mytopic.eastus-1.eventgrid.azure.net/api/events"),
credential);
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));
EventGridEvent egEvent = new(
subject: "orders/12345",
eventType: "Order.Created",
dataVersion: "1.0",
data: new { OrderId = "12345", Amount = 99.99 });
await client.SendEventAsync(egEvent);
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);
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
List<EventGridEvent> events = new()
{
new EventGridEvent(
subject: "orders/12345",
eventType: "Order.Created",
dataVersion: "1.0",
data: new { OrderId = "12345" })
{
Topic = "orders-topic"
},
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 par tirage (Espaces de noms)
Envoyer des événements à une rubrique d'espace de noms
using Azure;
using Azure.Messaging;
using Azure.Messaging.EventGrid.Namespaces;
var senderClient = new EventGridSenderClient(
new Uri(namespaceEndpoint),
topicName,
new AzureKeyCredential(topicKey));
CloudEvent cloudEvent = new("employee_source", "Employee.Created",
new { Name = "John", Age = 30 });
await senderClient.SendAsync(cloudEvent);
await senderClient.SendAsync(new[]
{
new CloudEvent("source", "type", new { Name = "Alice" }),
new CloudEvent("source", "type", new { Name = "Bob" })
});
Recevoir et traiter des événements
var receiverClient = new EventGridReceiverClient(
new Uri(namespaceEndpoint),
topicName,
subscriptionName,
new AzureKeyCredential(topicKey));
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
{
Console.WriteLine($"Événement : {cloudEvent.Type}, Données : {cloudEvent.Data}");
lockTokensToAck.Add(lockToken);
}
catch (Exception)
{
lockTokensToRelease.Add(lockToken);
}
}
if (lockTokensToAck.Any())
{
await receiverClient.AcknowledgeAsync(lockTokensToAck);
}
if (lockTokensToRelease.Any())
{
await receiverClient.ReleaseAsync(lockTokensToRelease);
}
Rejeter des événements (Lettre morte)
await receiverClient.RejectAsync(new[] { lockToken });
Consommation d'é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($"Type d'événement : {eventGridEvent.EventType}");
log.LogInformation($"Sujet : {eventGridEvent.Subject}");
log.LogInformation($"Données : {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($"Type d'événement : {cloudEvent.Type}");
logger.LogInformation($"Source : {cloudEvent.Source}");
logger.LogInformation($"Données : {cloudEvent.Data}");
}
}
Analyse d'événements
Analyser EventGridEvent
string json = "...";
EventGridEvent[] events = EventGridEvent.ParseMany(BinaryData.FromString(json));
foreach (EventGridEvent egEvent in events)
{
if (egEvent.TryGetSystemEventData(out object systemEvent))
{
switch (systemEvent)
{
case StorageBlobCreatedEventData blobCreated:
Console.WriteLine($"Blob créé : {blobCreated.Url}");
break;
}
}
else
{
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}, Données : {data}");
}
Événements système
using Azure.Messaging.EventGrid.SystemEvents;
StorageBlobCreatedEventData blobCreated;
StorageBlobDeletedEventData blobDeleted;
ResourceWriteSuccessEventData resourceCreated;
ResourceDeleteSuccessEventData resourceDeleted;
WebAppUpdatedEventData webAppUpdated;
ContainerRegistryImagePushedEventData imagePushed;
IotHubDeviceCreatedEventData deviceCreated;
Référence des types clés
| Type | Objectif |
|---|
EventGridPublisherClient | Publier sur des rubriques/domaines |
EventGridSenderClient | Envoyer vers des rubriques d'espace de noms |
EventGridReceiverClient | Recevoir depuis des abonnements d'espace de noms |
EventGridEvent | Schéma natif Event Grid |
CloudEvent | Schéma CloudEvents 1.0 |
ReceiveResult | Réponse de livraison par tirage |
ReceiveDetails | Événement avec propriétés du broker |
BrokerProperties | Jeton de verrouillage, nombre de livraisons |
Comparaison des schémas d'événements
| 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 | Multi-plateforme |
Bonnes pratiques
- Utilisez CloudEvents — Privilégiez CloudEvents pour les nouvelles implémentations (standard industriel)
- Regroupez les événements — Envoyez plusieurs événements en un seul appel pour plus d'efficacité
- Utilisez Entra ID — Préférez l'identité managée aux clés d'accès
- Gestionnaires idempotents — Les événements peuvent être livrés plusieurs fois
- Définissez la TTL des événements — Configurez la durée de vie pour les événements d'espace de noms
- Gérez les échecs partiels — Accusez réception/libérez les événements individuellement
- Utilisez la lettre morte — Configurez la lettre morte pour les événements en échec
- Validez les schémas — Validez 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("Échec de l'authentification - vérifiez les informations d'identification");
}
catch (RequestFailedException ex) when (ex.Status == 403)
{
Console.WriteLine("Échec de l'autorisation - vérifiez les autorisations RBAC");
}
catch (RequestFailedException ex) when (ex.Status == 413)
{
Console.WriteLine("Charge utile trop volumineuse - max 1 Mo par événement, 1 Mo total par lot");
}
catch (RequestFailedException ex)
{
Console.WriteLine($"Erreur Event Grid : {ex.Status} - {ex.Message}");
}
Modèle de basculement
try
{
var primaryClient = new EventGridPublisherClient(primaryUri, primaryKey);
await primaryClient.SendEventsAsync(events);
}
catch (RequestFailedException)
{
var secondaryClient = new EventGridPublisherClient(secondaryUri, secondaryKey);
await secondaryClient.SendEventsAsync(events);
}
Kits SDK associés
| SDK | Objectif | Installation |
|---|
Azure.Messaging.EventGrid | Rubriques/Domaines (ce SDK) | dotnet add package Azure.Messaging.EventGrid |
Azure.Messaging.EventGrid.Namespaces | Livraison par tirage | 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