[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CS2ZPVNR3PBSRAQDKYXK83":3,"skill-same:01M6CS2ZPVNR3PBSRAQDKYXK83":57},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":28,"linkOnly":29,"markdownContent":30,"markdownBody":31,"frontMatter":32,"refName":35,"commitSha":36,"skillDirectory":37,"forksCount":38,"repositoryHtmlUrl":39,"repositoryHomepageUrl":39,"ownerHtmlUrl":40,"ownerBlogUrl":6,"ownerDescription":41,"updatedAt":42,"install":43,"resources":56},"01M6CS2ZPVNR3PBSRAQDKYXK83","azure-eventgrid-dotnet",null,"Azure Event Grid SDK for .NET. Client library for publishing and consuming events with Azure Event Grid. Use for event-driven architectures, pub\u002Fsub messaging, CloudEvents, and EventGridEvents.","Sam-06060\u002Fjarvis-assistant","Sam-06060","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F208600848?v=4","01M6CRKT7C7FXD21V6HXF293S0","Samson Frank Ganta","01M6CRKTBEKYFD8YX5Z1GT99EE",6,"Apache-2.0","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fazure-eventgrid-dotnet\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27],"dotnet","azure","azure eventgrid dotnet","sdk","messaging","library","use","publishing","community","2026-11-10 10:12:30",false,"---\nname: azure-eventgrid-dotnet\ndescription: Azure Event Grid SDK for .NET. Client library for publishing and consuming events with Azure Event Grid. Use for event-driven architectures, pub\u002Fsub messaging, CloudEvents, and EventGridEvents.\nrisk: unknown\nsource: community\ndate_added: '2026-02-27'\n---\n\n# Azure.Messaging.EventGrid (.NET)\n\nClient library for publishing events to Azure Event Grid topics, domains, and namespaces.\n\n## Installation\n\n```bash\n# For topics and domains (push delivery)\ndotnet add package Azure.Messaging.EventGrid\n\n# For namespaces (pull delivery)\ndotnet add package Azure.Messaging.EventGrid.Namespaces\n\n# For CloudNative CloudEvents interop\ndotnet add package Microsoft.Azure.Messaging.EventGrid.CloudNativeCloudEvents\n```\n\n**Current Version**: 4.28.0 (stable)\n\n## Environment Variables\n\n```bash\n# Topic\u002FDomain endpoint\nEVENT_GRID_TOPIC_ENDPOINT=https:\u002F\u002F\u003Ctopic-name>.\u003Cregion>.eventgrid.azure.net\u002Fapi\u002Fevents\nEVENT_GRID_TOPIC_KEY=\u003Caccess-key>\n\n# Namespace endpoint (for pull delivery)\nEVENT_GRID_NAMESPACE_ENDPOINT=https:\u002F\u002F\u003Cnamespace>.\u003Cregion>.eventgrid.azure.net\nEVENT_GRID_TOPIC_NAME=\u003Ctopic-name>\nEVENT_GRID_SUBSCRIPTION_NAME=\u003Csubscription-name>\n```\n\n## Client Hierarchy\n\n```\nPush Delivery (Topics\u002FDomains)\n└── EventGridPublisherClient\n    ├── SendEventAsync(EventGridEvent)\n    ├── SendEventsAsync(IEnumerable\u003CEventGridEvent>)\n    ├── SendEventAsync(CloudEvent)\n    └── SendEventsAsync(IEnumerable\u003CCloudEvent>)\n\nPull Delivery (Namespaces)\n├── EventGridSenderClient\n│   └── SendAsync(CloudEvent)\n└── EventGridReceiverClient\n    ├── ReceiveAsync()\n    ├── AcknowledgeAsync()\n    ├── ReleaseAsync()\n    └── RejectAsync()\n```\n\n## Authentication\n\n### API Key Authentication\n\n```csharp\nusing Azure;\nusing Azure.Messaging.EventGrid;\n\nEventGridPublisherClient client = new(\n    new Uri(\"https:\u002F\u002Fmytopic.eastus-1.eventgrid.azure.net\u002Fapi\u002Fevents\"),\n    new AzureKeyCredential(\"\u003Caccess-key>\"));\n```\n\n### Microsoft Entra ID (Recommended)\n\n```csharp\nusing Azure.Identity;\nusing Azure.Messaging.EventGrid;\n\nEventGridPublisherClient client = new(\n    new Uri(\"https:\u002F\u002Fmytopic.eastus-1.eventgrid.azure.net\u002Fapi\u002Fevents\"),\n    new DefaultAzureCredential());\n```\n\n### SAS Token Authentication\n\n```csharp\nstring sasToken = EventGridPublisherClient.BuildSharedAccessSignature(\n    new Uri(topicEndpoint),\n    DateTimeOffset.UtcNow.AddHours(1),\n    new AzureKeyCredential(topicKey));\n\nvar sasCredential = new AzureSasCredential(sasToken);\nEventGridPublisherClient client = new(\n    new Uri(topicEndpoint),\n    sasCredential);\n```\n\n## Publishing Events\n\n### EventGridEvent Schema\n\n```csharp\nEventGridPublisherClient client = new(\n    new Uri(topicEndpoint),\n    new AzureKeyCredential(topicKey));\n\n\u002F\u002F Single event\nEventGridEvent egEvent = new(\n    subject: \"orders\u002F12345\",\n    eventType: \"Order.Created\",\n    dataVersion: \"1.0\",\n    data: new { OrderId = \"12345\", Amount = 99.99 });\n\nawait client.SendEventAsync(egEvent);\n\n\u002F\u002F Batch of events\nList\u003CEventGridEvent> events = new()\n{\n    new EventGridEvent(\n        subject: \"orders\u002F12345\",\n        eventType: \"Order.Created\",\n        dataVersion: \"1.0\",\n        data: new OrderData { OrderId = \"12345\", Amount = 99.99 }),\n    new EventGridEvent(\n        subject: \"orders\u002F12346\",\n        eventType: \"Order.Created\",\n        dataVersion: \"1.0\",\n        data: new OrderData { OrderId = \"12346\", Amount = 149.99 })\n};\n\nawait client.SendEventsAsync(events);\n```\n\n### CloudEvent Schema\n\n```csharp\nCloudEvent cloudEvent = new(\n    source: \"\u002Forders\u002Fsystem\",\n    type: \"Order.Created\",\n    data: new { OrderId = \"12345\", Amount = 99.99 });\n\ncloudEvent.Subject = \"orders\u002F12345\";\ncloudEvent.Id = Guid.NewGuid().ToString();\ncloudEvent.Time = DateTimeOffset.UtcNow;\n\nawait client.SendEventAsync(cloudEvent);\n\n\u002F\u002F Batch of CloudEvents\nList\u003CCloudEvent> cloudEvents = new()\n{\n    new CloudEvent(\"\u002Forders\", \"Order.Created\", new { OrderId = \"1\" }),\n    new CloudEvent(\"\u002Forders\", \"Order.Updated\", new { OrderId = \"2\" })\n};\n\nawait client.SendEventsAsync(cloudEvents);\n```\n\n### Publishing to Event Grid Domain\n\n```csharp\n\u002F\u002F Events must specify the Topic property for domain routing\nList\u003CEventGridEvent> events = new()\n{\n    new EventGridEvent(\n        subject: \"orders\u002F12345\",\n        eventType: \"Order.Created\",\n        dataVersion: \"1.0\",\n        data: new { OrderId = \"12345\" })\n    {\n        Topic = \"orders-topic\"  \u002F\u002F Domain topic name\n    },\n    new EventGridEvent(\n        subject: \"inventory\u002Fitem-1\",\n        eventType: \"Inventory.Updated\",\n        dataVersion: \"1.0\",\n        data: new { ItemId = \"item-1\" })\n    {\n        Topic = \"inventory-topic\"\n    }\n};\n\nawait client.SendEventsAsync(events);\n```\n\n### Custom Serialization\n\n```csharp\nusing System.Text.Json;\n\nvar serializerOptions = new JsonSerializerOptions\n{\n    PropertyNamingPolicy = JsonNamingPolicy.CamelCase\n};\n\nvar customSerializer = new JsonObjectSerializer(serializerOptions);\n\nEventGridEvent egEvent = new(\n    subject: \"orders\u002F12345\",\n    eventType: \"Order.Created\",\n    dataVersion: \"1.0\",\n    data: customSerializer.Serialize(new OrderData { OrderId = \"12345\" }));\n\nawait client.SendEventAsync(egEvent);\n```\n\n## Pull Delivery (Namespaces)\n\n### Send Events to Namespace Topic\n\n```csharp\nusing Azure;\nusing Azure.Messaging;\nusing Azure.Messaging.EventGrid.Namespaces;\n\nvar senderClient = new EventGridSenderClient(\n    new Uri(namespaceEndpoint),\n    topicName,\n    new AzureKeyCredential(topicKey));\n\n\u002F\u002F Send single event\nCloudEvent cloudEvent = new(\"employee_source\", \"Employee.Created\", \n    new { Name = \"John\", Age = 30 });\nawait senderClient.SendAsync(cloudEvent);\n\n\u002F\u002F Send batch\nawait senderClient.SendAsync(new[]\n{\n    new CloudEvent(\"source\", \"type\", new { Name = \"Alice\" }),\n    new CloudEvent(\"source\", \"type\", new { Name = \"Bob\" })\n});\n```\n\n### Receive and Process Events\n\n```csharp\nvar receiverClient = new EventGridReceiverClient(\n    new Uri(namespaceEndpoint),\n    topicName,\n    subscriptionName,\n    new AzureKeyCredential(topicKey));\n\n\u002F\u002F Receive events\nReceiveResult result = await receiverClient.ReceiveAsync(maxEvents: 10);\n\nList\u003Cstring> lockTokensToAck = new();\nList\u003Cstring> lockTokensToRelease = new();\n\nforeach (ReceiveDetails detail in result.Details)\n{\n    CloudEvent cloudEvent = detail.Event;\n    string lockToken = detail.BrokerProperties.LockToken;\n    \n    try\n    {\n        \u002F\u002F Process the event\n        Console.WriteLine($\"Event: {cloudEvent.Type}, Data: {cloudEvent.Data}\");\n        lockTokensToAck.Add(lockToken);\n    }\n    catch (Exception)\n    {\n        \u002F\u002F Release for retry\n        lockTokensToRelease.Add(lockToken);\n    }\n}\n\n\u002F\u002F Acknowledge successfully processed events\nif (lockTokensToAck.Any())\n{\n    await receiverClient.AcknowledgeAsync(lockTokensToAck);\n}\n\n\u002F\u002F Release events for retry\nif (lockTokensToRelease.Any())\n{\n    await receiverClient.ReleaseAsync(lockTokensToRelease);\n}\n```\n\n### Reject Events (Dead Letter)\n\n```csharp\n\u002F\u002F Reject events that cannot be processed\nawait receiverClient.RejectAsync(new[] { lockToken });\n```\n\n## Consuming Events (Azure Functions)\n\n### EventGridEvent Trigger\n\n```csharp\nusing Azure.Messaging.EventGrid;\nusing Microsoft.Azure.WebJobs;\nusing Microsoft.Azure.WebJobs.Extensions.EventGrid;\n\npublic static class EventGridFunction\n{\n    [FunctionName(\"ProcessEventGridEvent\")]\n    public static void Run(\n        [EventGridTrigger] EventGridEvent eventGridEvent,\n        ILogger log)\n    {\n        log.LogInformation($\"Event Type: {eventGridEvent.EventType}\");\n        log.LogInformation($\"Subject: {eventGridEvent.Subject}\");\n        log.LogInformation($\"Data: {eventGridEvent.Data}\");\n    }\n}\n```\n\n### CloudEvent Trigger\n\n```csharp\nusing Azure.Messaging;\nusing Microsoft.Azure.Functions.Worker;\n\npublic class CloudEventFunction\n{\n    [Function(\"ProcessCloudEvent\")]\n    public void Run(\n        [EventGridTrigger] CloudEvent cloudEvent,\n        FunctionContext context)\n    {\n        var logger = context.GetLogger(\"ProcessCloudEvent\");\n        logger.LogInformation($\"Event Type: {cloudEvent.Type}\");\n        logger.LogInformation($\"Source: {cloudEvent.Source}\");\n        logger.LogInformation($\"Data: {cloudEvent.Data}\");\n    }\n}\n```\n\n## Parsing Events\n\n### Parse EventGridEvent\n\n```csharp\n\u002F\u002F From JSON string\nstring json = \"...\"; \u002F\u002F Event Grid webhook payload\nEventGridEvent[] events = EventGridEvent.ParseMany(BinaryData.FromString(json));\n\nforeach (EventGridEvent egEvent in events)\n{\n    if (egEvent.TryGetSystemEventData(out object systemEvent))\n    {\n        \u002F\u002F Handle system event\n        switch (systemEvent)\n        {\n            case StorageBlobCreatedEventData blobCreated:\n                Console.WriteLine($\"Blob created: {blobCreated.Url}\");\n                break;\n        }\n    }\n    else\n    {\n        \u002F\u002F Handle custom event\n        var customData = egEvent.Data.ToObjectFromJson\u003CMyCustomData>();\n    }\n}\n```\n\n### Parse CloudEvent\n\n```csharp\nCloudEvent[] cloudEvents = CloudEvent.ParseMany(BinaryData.FromString(json));\n\nforeach (CloudEvent cloudEvent in cloudEvents)\n{\n    var data = cloudEvent.Data.ToObjectFromJson\u003CMyEventData>();\n    Console.WriteLine($\"Type: {cloudEvent.Type}, Data: {data}\");\n}\n```\n\n## System Events\n\n```csharp\n\u002F\u002F Common system event types\nusing Azure.Messaging.EventGrid.SystemEvents;\n\n\u002F\u002F Storage events\nStorageBlobCreatedEventData blobCreated;\nStorageBlobDeletedEventData blobDeleted;\n\n\u002F\u002F Resource events\nResourceWriteSuccessEventData resourceCreated;\nResourceDeleteSuccessEventData resourceDeleted;\n\n\u002F\u002F App Service events\nWebAppUpdatedEventData webAppUpdated;\n\n\u002F\u002F Container Registry events\nContainerRegistryImagePushedEventData imagePushed;\n\n\u002F\u002F IoT Hub events\nIotHubDeviceCreatedEventData deviceCreated;\n```\n\n## Key Types Reference\n\n| Type | Purpose |\n|------|---------|\n| `EventGridPublisherClient` | Publish to topics\u002Fdomains |\n| `EventGridSenderClient` | Send to namespace topics |\n| `EventGridReceiverClient` | Receive from namespace subscriptions |\n| `EventGridEvent` | Event Grid native schema |\n| `CloudEvent` | CloudEvents 1.0 schema |\n| `ReceiveResult` | Pull delivery response |\n| `ReceiveDetails` | Event with broker properties |\n| `BrokerProperties` | Lock token, delivery count |\n\n## Event Schemas Comparison\n\n| Feature | EventGridEvent | CloudEvent |\n|---------|----------------|------------|\n| Standard | Azure-specific | CNCF standard |\n| Required fields | subject, eventType, dataVersion, data | source, type |\n| Extensibility | Limited | Extension attributes |\n| Interoperability | Azure only | Cross-platform |\n\n## Best Practices\n\n1. **Use CloudEvents** — Prefer CloudEvents for new implementations (industry standard)\n2. **Batch events** — Send multiple events in one call for efficiency\n3. **Use Entra ID** — Prefer managed identity over access keys\n4. **Idempotent handlers** — Events may be delivered more than once\n5. **Set event TTL** — Configure time-to-live for namespace events\n6. **Handle partial failures** — Acknowledge\u002Frelease events individually\n7. **Use dead-letter** — Configure dead-letter for failed events\n8. **Validate schemas** — Validate event data before processing\n\n## Error Handling\n\n```csharp\nusing Azure;\n\ntry\n{\n    await client.SendEventAsync(cloudEvent);\n}\ncatch (RequestFailedException ex) when (ex.Status == 401)\n{\n    Console.WriteLine(\"Authentication failed - check credentials\");\n}\ncatch (RequestFailedException ex) when (ex.Status == 403)\n{\n    Console.WriteLine(\"Authorization failed - check RBAC permissions\");\n}\ncatch (RequestFailedException ex) when (ex.Status == 413)\n{\n    Console.WriteLine(\"Payload too large - max 1MB per event, 1MB total batch\");\n}\ncatch (RequestFailedException ex)\n{\n    Console.WriteLine($\"Event Grid error: {ex.Status} - {ex.Message}\");\n}\n```\n\n## Failover Pattern\n\n```csharp\ntry\n{\n    var primaryClient = new EventGridPublisherClient(primaryUri, primaryKey);\n    await primaryClient.SendEventsAsync(events);\n}\ncatch (RequestFailedException)\n{\n    \u002F\u002F Failover to secondary region\n    var secondaryClient = new EventGridPublisherClient(secondaryUri, secondaryKey);\n    await secondaryClient.SendEventsAsync(events);\n}\n```\n\n## Related SDKs\n\n| SDK | Purpose | Install |\n|-----|---------|---------|\n| `Azure.Messaging.EventGrid` | Topics\u002FDomains (this SDK) | `dotnet add package Azure.Messaging.EventGrid` |\n| `Azure.Messaging.EventGrid.Namespaces` | Pull delivery | `dotnet add package Azure.Messaging.EventGrid.Namespaces` |\n| `Azure.Identity` | Authentication | `dotnet add package Azure.Identity` |\n| `Microsoft.Azure.WebJobs.Extensions.EventGrid` | Azure Functions trigger | `dotnet add package Microsoft.Azure.WebJobs.Extensions.EventGrid` |\n\n## Reference Links\n\n| Resource | URL |\n|----------|-----|\n| NuGet Package | https:\u002F\u002Fwww.nuget.org\u002Fpackages\u002FAzure.Messaging.EventGrid |\n| API Reference | https:\u002F\u002Flearn.microsoft.com\u002Fdotnet\u002Fapi\u002Fazure.messaging.eventgrid |\n| Quickstart | https:\u002F\u002Flearn.microsoft.com\u002Fazure\u002Fevent-grid\u002Fcustom-event-quickstart |\n| Pull Delivery | https:\u002F\u002Flearn.microsoft.com\u002Fazure\u002Fevent-grid\u002Fpull-delivery-overview |\n| GitHub Source | https:\u002F\u002Fgithub.com\u002FAzure\u002Fazure-sdk-for-net\u002Ftree\u002Fmain\u002Fsdk\u002Feventgrid\u002FAzure.Messaging.EventGrid |\n\n## When to Use\nThis skill is applicable to execute the workflow or actions described in the overview.\n","# Azure.Messaging.EventGrid (.NET)\n\nClient library for publishing events to Azure Event Grid topics, domains, and namespaces.\n\n## Installation\n\n```bash\n# For topics and domains (push delivery)\ndotnet add package Azure.Messaging.EventGrid\n\n# For namespaces (pull delivery)\ndotnet add package Azure.Messaging.EventGrid.Namespaces\n\n# For CloudNative CloudEvents interop\ndotnet add package Microsoft.Azure.Messaging.EventGrid.CloudNativeCloudEvents\n```\n\n**Current Version**: 4.28.0 (stable)\n\n## Environment Variables\n\n```bash\n# Topic\u002FDomain endpoint\nEVENT_GRID_TOPIC_ENDPOINT=https:\u002F\u002F\u003Ctopic-name>.\u003Cregion>.eventgrid.azure.net\u002Fapi\u002Fevents\nEVENT_GRID_TOPIC_KEY=\u003Caccess-key>\n\n# Namespace endpoint (for pull delivery)\nEVENT_GRID_NAMESPACE_ENDPOINT=https:\u002F\u002F\u003Cnamespace>.\u003Cregion>.eventgrid.azure.net\nEVENT_GRID_TOPIC_NAME=\u003Ctopic-name>\nEVENT_GRID_SUBSCRIPTION_NAME=\u003Csubscription-name>\n```\n\n## Client Hierarchy\n\n```\nPush Delivery (Topics\u002FDomains)\n└── EventGridPublisherClient\n    ├── SendEventAsync(EventGridEvent)\n    ├── SendEventsAsync(IEnumerable\u003CEventGridEvent>)\n    ├── SendEventAsync(CloudEvent)\n    └── SendEventsAsync(IEnumerable\u003CCloudEvent>)\n\nPull Delivery (Namespaces)\n├── EventGridSenderClient\n│   └── SendAsync(CloudEvent)\n└── EventGridReceiverClient\n    ├── ReceiveAsync()\n    ├── AcknowledgeAsync()\n    ├── ReleaseAsync()\n    └── RejectAsync()\n```\n\n## Authentication\n\n### API Key Authentication\n\n```csharp\nusing Azure;\nusing Azure.Messaging.EventGrid;\n\nEventGridPublisherClient client = new(\n    new Uri(\"https:\u002F\u002Fmytopic.eastus-1.eventgrid.azure.net\u002Fapi\u002Fevents\"),\n    new AzureKeyCredential(\"\u003Caccess-key>\"));\n```\n\n### Microsoft Entra ID (Recommended)\n\n```csharp\nusing Azure.Identity;\nusing Azure.Messaging.EventGrid;\n\nEventGridPublisherClient client = new(\n    new Uri(\"https:\u002F\u002Fmytopic.eastus-1.eventgrid.azure.net\u002Fapi\u002Fevents\"),\n    new DefaultAzureCredential());\n```\n\n### SAS Token Authentication\n\n```csharp\nstring sasToken = EventGridPublisherClient.BuildSharedAccessSignature(\n    new Uri(topicEndpoint),\n    DateTimeOffset.UtcNow.AddHours(1),\n    new AzureKeyCredential(topicKey));\n\nvar sasCredential = new AzureSasCredential(sasToken);\nEventGridPublisherClient client = new(\n    new Uri(topicEndpoint),\n    sasCredential);\n```\n\n## Publishing Events\n\n### EventGridEvent Schema\n\n```csharp\nEventGridPublisherClient client = new(\n    new Uri(topicEndpoint),\n    new AzureKeyCredential(topicKey));\n\n\u002F\u002F Single event\nEventGridEvent egEvent = new(\n    subject: \"orders\u002F12345\",\n    eventType: \"Order.Created\",\n    dataVersion: \"1.0\",\n    data: new { OrderId = \"12345\", Amount = 99.99 });\n\nawait client.SendEventAsync(egEvent);\n\n\u002F\u002F Batch of events\nList\u003CEventGridEvent> events = new()\n{\n    new EventGridEvent(\n        subject: \"orders\u002F12345\",\n        eventType: \"Order.Created\",\n        dataVersion: \"1.0\",\n        data: new OrderData { OrderId = \"12345\", Amount = 99.99 }),\n    new EventGridEvent(\n        subject: \"orders\u002F12346\",\n        eventType: \"Order.Created\",\n        dataVersion: \"1.0\",\n        data: new OrderData { OrderId = \"12346\", Amount = 149.99 })\n};\n\nawait client.SendEventsAsync(events);\n```\n\n### CloudEvent Schema\n\n```csharp\nCloudEvent cloudEvent = new(\n    source: \"\u002Forders\u002Fsystem\",\n    type: \"Order.Created\",\n    data: new { OrderId = \"12345\", Amount = 99.99 });\n\ncloudEvent.Subject = \"orders\u002F12345\";\ncloudEvent.Id = Guid.NewGuid().ToString();\ncloudEvent.Time = DateTimeOffset.UtcNow;\n\nawait client.SendEventAsync(cloudEvent);\n\n\u002F\u002F Batch of CloudEvents\nList\u003CCloudEvent> cloudEvents = new()\n{\n    new CloudEvent(\"\u002Forders\", \"Order.Created\", new { OrderId = \"1\" }),\n    new CloudEvent(\"\u002Forders\", \"Order.Updated\", new { OrderId = \"2\" })\n};\n\nawait client.SendEventsAsync(cloudEvents);\n```\n\n### Publishing to Event Grid Domain\n\n```csharp\n\u002F\u002F Events must specify the Topic property for domain routing\nList\u003CEventGridEvent> events = new()\n{\n    new EventGridEvent(\n        subject: \"orders\u002F12345\",\n        eventType: \"Order.Created\",\n        dataVersion: \"1.0\",\n        data: new { OrderId = \"12345\" })\n    {\n        Topic = \"orders-topic\"  \u002F\u002F Domain topic name\n    },\n    new EventGridEvent(\n        subject: \"inventory\u002Fitem-1\",\n        eventType: \"Inventory.Updated\",\n        dataVersion: \"1.0\",\n        data: new { ItemId = \"item-1\" })\n    {\n        Topic = \"inventory-topic\"\n    }\n};\n\nawait client.SendEventsAsync(events);\n```\n\n### Custom Serialization\n\n```csharp\nusing System.Text.Json;\n\nvar serializerOptions = new JsonSerializerOptions\n{\n    PropertyNamingPolicy = JsonNamingPolicy.CamelCase\n};\n\nvar customSerializer = new JsonObjectSerializer(serializerOptions);\n\nEventGridEvent egEvent = new(\n    subject: \"orders\u002F12345\",\n    eventType: \"Order.Created\",\n    dataVersion: \"1.0\",\n    data: customSerializer.Serialize(new OrderData { OrderId = \"12345\" }));\n\nawait client.SendEventAsync(egEvent);\n```\n\n## Pull Delivery (Namespaces)\n\n### Send Events to Namespace Topic\n\n```csharp\nusing Azure;\nusing Azure.Messaging;\nusing Azure.Messaging.EventGrid.Namespaces;\n\nvar senderClient = new EventGridSenderClient(\n    new Uri(namespaceEndpoint),\n    topicName,\n    new AzureKeyCredential(topicKey));\n\n\u002F\u002F Send single event\nCloudEvent cloudEvent = new(\"employee_source\", \"Employee.Created\", \n    new { Name = \"John\", Age = 30 });\nawait senderClient.SendAsync(cloudEvent);\n\n\u002F\u002F Send batch\nawait senderClient.SendAsync(new[]\n{\n    new CloudEvent(\"source\", \"type\", new { Name = \"Alice\" }),\n    new CloudEvent(\"source\", \"type\", new { Name = \"Bob\" })\n});\n```\n\n### Receive and Process Events\n\n```csharp\nvar receiverClient = new EventGridReceiverClient(\n    new Uri(namespaceEndpoint),\n    topicName,\n    subscriptionName,\n    new AzureKeyCredential(topicKey));\n\n\u002F\u002F Receive events\nReceiveResult result = await receiverClient.ReceiveAsync(maxEvents: 10);\n\nList\u003Cstring> lockTokensToAck = new();\nList\u003Cstring> lockTokensToRelease = new();\n\nforeach (ReceiveDetails detail in result.Details)\n{\n    CloudEvent cloudEvent = detail.Event;\n    string lockToken = detail.BrokerProperties.LockToken;\n    \n    try\n    {\n        \u002F\u002F Process the event\n        Console.WriteLine($\"Event: {cloudEvent.Type}, Data: {cloudEvent.Data}\");\n        lockTokensToAck.Add(lockToken);\n    }\n    catch (Exception)\n    {\n        \u002F\u002F Release for retry\n        lockTokensToRelease.Add(lockToken);\n    }\n}\n\n\u002F\u002F Acknowledge successfully processed events\nif (lockTokensToAck.Any())\n{\n    await receiverClient.AcknowledgeAsync(lockTokensToAck);\n}\n\n\u002F\u002F Release events for retry\nif (lockTokensToRelease.Any())\n{\n    await receiverClient.ReleaseAsync(lockTokensToRelease);\n}\n```\n\n### Reject Events (Dead Letter)\n\n```csharp\n\u002F\u002F Reject events that cannot be processed\nawait receiverClient.RejectAsync(new[] { lockToken });\n```\n\n## Consuming Events (Azure Functions)\n\n### EventGridEvent Trigger\n\n```csharp\nusing Azure.Messaging.EventGrid;\nusing Microsoft.Azure.WebJobs;\nusing Microsoft.Azure.WebJobs.Extensions.EventGrid;\n\npublic static class EventGridFunction\n{\n    [FunctionName(\"ProcessEventGridEvent\")]\n    public static void Run(\n        [EventGridTrigger] EventGridEvent eventGridEvent,\n        ILogger log)\n    {\n        log.LogInformation($\"Event Type: {eventGridEvent.EventType}\");\n        log.LogInformation($\"Subject: {eventGridEvent.Subject}\");\n        log.LogInformation($\"Data: {eventGridEvent.Data}\");\n    }\n}\n```\n\n### CloudEvent Trigger\n\n```csharp\nusing Azure.Messaging;\nusing Microsoft.Azure.Functions.Worker;\n\npublic class CloudEventFunction\n{\n    [Function(\"ProcessCloudEvent\")]\n    public void Run(\n        [EventGridTrigger] CloudEvent cloudEvent,\n        FunctionContext context)\n    {\n        var logger = context.GetLogger(\"ProcessCloudEvent\");\n        logger.LogInformation($\"Event Type: {cloudEvent.Type}\");\n        logger.LogInformation($\"Source: {cloudEvent.Source}\");\n        logger.LogInformation($\"Data: {cloudEvent.Data}\");\n    }\n}\n```\n\n## Parsing Events\n\n### Parse EventGridEvent\n\n```csharp\n\u002F\u002F From JSON string\nstring json = \"...\"; \u002F\u002F Event Grid webhook payload\nEventGridEvent[] events = EventGridEvent.ParseMany(BinaryData.FromString(json));\n\nforeach (EventGridEvent egEvent in events)\n{\n    if (egEvent.TryGetSystemEventData(out object systemEvent))\n    {\n        \u002F\u002F Handle system event\n        switch (systemEvent)\n        {\n            case StorageBlobCreatedEventData blobCreated:\n                Console.WriteLine($\"Blob created: {blobCreated.Url}\");\n                break;\n        }\n    }\n    else\n    {\n        \u002F\u002F Handle custom event\n        var customData = egEvent.Data.ToObjectFromJson\u003CMyCustomData>();\n    }\n}\n```\n\n### Parse CloudEvent\n\n```csharp\nCloudEvent[] cloudEvents = CloudEvent.ParseMany(BinaryData.FromString(json));\n\nforeach (CloudEvent cloudEvent in cloudEvents)\n{\n    var data = cloudEvent.Data.ToObjectFromJson\u003CMyEventData>();\n    Console.WriteLine($\"Type: {cloudEvent.Type}, Data: {data}\");\n}\n```\n\n## System Events\n\n```csharp\n\u002F\u002F Common system event types\nusing Azure.Messaging.EventGrid.SystemEvents;\n\n\u002F\u002F Storage events\nStorageBlobCreatedEventData blobCreated;\nStorageBlobDeletedEventData blobDeleted;\n\n\u002F\u002F Resource events\nResourceWriteSuccessEventData resourceCreated;\nResourceDeleteSuccessEventData resourceDeleted;\n\n\u002F\u002F App Service events\nWebAppUpdatedEventData webAppUpdated;\n\n\u002F\u002F Container Registry events\nContainerRegistryImagePushedEventData imagePushed;\n\n\u002F\u002F IoT Hub events\nIotHubDeviceCreatedEventData deviceCreated;\n```\n\n## Key Types Reference\n\n| Type | Purpose |\n|------|---------|\n| `EventGridPublisherClient` | Publish to topics\u002Fdomains |\n| `EventGridSenderClient` | Send to namespace topics |\n| `EventGridReceiverClient` | Receive from namespace subscriptions |\n| `EventGridEvent` | Event Grid native schema |\n| `CloudEvent` | CloudEvents 1.0 schema |\n| `ReceiveResult` | Pull delivery response |\n| `ReceiveDetails` | Event with broker properties |\n| `BrokerProperties` | Lock token, delivery count |\n\n## Event Schemas Comparison\n\n| Feature | EventGridEvent | CloudEvent |\n|---------|----------------|------------|\n| Standard | Azure-specific | CNCF standard |\n| Required fields | subject, eventType, dataVersion, data | source, type |\n| Extensibility | Limited | Extension attributes |\n| Interoperability | Azure only | Cross-platform |\n\n## Best Practices\n\n1. **Use CloudEvents** — Prefer CloudEvents for new implementations (industry standard)\n2. **Batch events** — Send multiple events in one call for efficiency\n3. **Use Entra ID** — Prefer managed identity over access keys\n4. **Idempotent handlers** — Events may be delivered more than once\n5. **Set event TTL** — Configure time-to-live for namespace events\n6. **Handle partial failures** — Acknowledge\u002Frelease events individually\n7. **Use dead-letter** — Configure dead-letter for failed events\n8. **Validate schemas** — Validate event data before processing\n\n## Error Handling\n\n```csharp\nusing Azure;\n\ntry\n{\n    await client.SendEventAsync(cloudEvent);\n}\ncatch (RequestFailedException ex) when (ex.Status == 401)\n{\n    Console.WriteLine(\"Authentication failed - check credentials\");\n}\ncatch (RequestFailedException ex) when (ex.Status == 403)\n{\n    Console.WriteLine(\"Authorization failed - check RBAC permissions\");\n}\ncatch (RequestFailedException ex) when (ex.Status == 413)\n{\n    Console.WriteLine(\"Payload too large - max 1MB per event, 1MB total batch\");\n}\ncatch (RequestFailedException ex)\n{\n    Console.WriteLine($\"Event Grid error: {ex.Status} - {ex.Message}\");\n}\n```\n\n## Failover Pattern\n\n```csharp\ntry\n{\n    var primaryClient = new EventGridPublisherClient(primaryUri, primaryKey);\n    await primaryClient.SendEventsAsync(events);\n}\ncatch (RequestFailedException)\n{\n    \u002F\u002F Failover to secondary region\n    var secondaryClient = new EventGridPublisherClient(secondaryUri, secondaryKey);\n    await secondaryClient.SendEventsAsync(events);\n}\n```\n\n## Related SDKs\n\n| SDK | Purpose | Install |\n|-----|---------|---------|\n| `Azure.Messaging.EventGrid` | Topics\u002FDomains (this SDK) | `dotnet add package Azure.Messaging.EventGrid` |\n| `Azure.Messaging.EventGrid.Namespaces` | Pull delivery | `dotnet add package Azure.Messaging.EventGrid.Namespaces` |\n| `Azure.Identity` | Authentication | `dotnet add package Azure.Identity` |\n| `Microsoft.Azure.WebJobs.Extensions.EventGrid` | Azure Functions trigger | `dotnet add package Microsoft.Azure.WebJobs.Extensions.EventGrid` |\n\n## Reference Links\n\n| Resource | URL |\n|----------|-----|\n| NuGet Package | https:\u002F\u002Fwww.nuget.org\u002Fpackages\u002FAzure.Messaging.EventGrid |\n| API Reference | https:\u002F\u002Flearn.microsoft.com\u002Fdotnet\u002Fapi\u002Fazure.messaging.eventgrid |\n| Quickstart | https:\u002F\u002Flearn.microsoft.com\u002Fazure\u002Fevent-grid\u002Fcustom-event-quickstart |\n| Pull Delivery | https:\u002F\u002Flearn.microsoft.com\u002Fazure\u002Fevent-grid\u002Fpull-delivery-overview |\n| GitHub Source | https:\u002F\u002Fgithub.com\u002FAzure\u002Fazure-sdk-for-net\u002Ftree\u002Fmain\u002Fsdk\u002Feventgrid\u002FAzure.Messaging.EventGrid |\n\n## When to Use\nThis skill is applicable to execute the workflow or actions described in the overview.\n",{"name":5,"risk":33,"source":27,"date_added":34,"description":7},"unknown","2026-02-27","main","a50a3aa6b39fb0e1b7db88bef1bfc9c93606e126","modules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fazure-eventgrid-dotnet",0,"https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant","https:\u002F\u002Fgithub.com\u002FSam-06060","Mobile Application Developer | Kotlin | Flutter, KMP, Swfit, Android,Swift UI | Building at Saar It Resources | Creator of Jarvis (AI Assistant)","2026-06-23 05:13:38",{"source":8,"skillName":5,"commands":44,"prompt":54,"zipAvailable":55},[45,48,51],{"tool":46,"command":47},"npx","npx skills add Sam-06060\u002Fjarvis-assistant --skill azure-eventgrid-dotnet",{"tool":49,"command":50},"bunx","bunx skills add Sam-06060\u002Fjarvis-assistant --skill azure-eventgrid-dotnet",{"tool":52,"command":53},"pnpm","pnpm dlx skills add Sam-06060\u002Fjarvis-assistant --skill azure-eventgrid-dotnet","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fazure-eventgrid-dotnet\u002FSKILL.md",true,[],[58,71,87,114,133,160],{"skillNo":59,"name":60,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":61,"categories":62,"keywords":68,"publishedAt":28},"01M6GDRVS6FXX3ESH0C9DW01C0","test_skill","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fscratch\u002Ftest_skill\u002FSKILL.md",[63],{"categoryNo":64,"categoryName":65,"taxonomyType":66,"taxonomyTypeDesc":67},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[69,70],"Test Skill","test",{"skillNo":72,"name":73,"nameZh":6,"description":74,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":75,"categories":76,"keywords":77,"publishedAt":28},"01M6GDRQ40HX22MA6XWC31RHHK","zustand-store-ts","Create Zustand stores following established patterns with proper TypeScript types and middleware.","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fzustand-store-ts\u002FSKILL.md",[],[78,79,80,81,82,83,84,27,85,86],"zustand store ts","zustand","store","with","types","middleware","patterns","create","typescript",{"skillNo":88,"name":89,"nameZh":6,"description":90,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":91,"categories":92,"keywords":96,"publishedAt":28},"01M6GDRKEA0WE670SPFWX5GKCN","zoom-automation","Automate Zoom meeting creation, management, recordings, webinars, and participant tracking via Rube MCP (Composio). Always search tools first for current schemas.","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fzoom-automation\u002FSKILL.md",[93],{"categoryNo":94,"categoryName":95,"taxonomyType":66,"taxonomyTypeDesc":67},"01JBSEEDCAT000000000000023","Skill与智能体开发",[97,98,99,100,101,102,103,104,105,106,107,108,109,110,27,111,112,113],"automation","zoom automation","zoom","first","Tools","search","MCP","via","meeting","automate","critical","creation","webinars","composio","recordings","management","tracking",{"skillNo":115,"name":116,"nameZh":6,"description":117,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":118,"categories":119,"keywords":121,"publishedAt":28},"01M6GDRFS1452PC71JQ38S24HR","zoho-crm-automation","Automate Zoho CRM tasks via Rube MCP (Composio): create\u002Fupdate records, search contacts, manage leads, and convert leads. Always search tools first for current schemas.","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fzoho-crm-automation\u002FSKILL.md",[120],{"categoryNo":94,"categoryName":95,"taxonomyType":66,"taxonomyTypeDesc":67},[122,97,123,124,125,126,127,27,102,128,110,129,107,106,101,130,85,131,103,132],"crm automation","zoho crm","crm","zoho crm automation","zoho","leads","contacts","records","update","tasks","manage",{"skillNo":134,"name":135,"nameZh":6,"description":136,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":137,"categories":138,"keywords":142,"publishedAt":28},"01M6GDRCKQBAVTGHX5XBH26KPZ","zod-validation-expert","Expert in Zod — TypeScript-first schema validation. Covers parsing, custom errors, refinements, type inference, and integration with React Hook Form, Next.js, and tRPC.","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fzod-validation-expert\u002FSKILL.md",[139],{"categoryNo":140,"categoryName":141,"taxonomyType":66,"taxonomyTypeDesc":67},"01JBSEEDCAT000000000000009","前端开发",[143,144,145,146,147,86,148,149,150,151,152,153,81,154,155,156,157,27,158,159],"expert","zod","zod validation expert","validation","react","safe","parsing","errors","schema validation","react hook form","hook","trpc","form","type","next","schema","Next.js",{"skillNo":161,"name":162,"nameZh":6,"description":163,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":164,"categories":165,"keywords":167,"publishedAt":28},"01M6GDR658B08K4MY0RWD4A6EH","zeroize-audit","Detects missing zeroization of sensitive data in source code and identifies zeroization removed by compiler optimizations, with assembly-level analysis, and control-flow verification. Use for auditing C\u002FC++\u002FRust code handling secrets, keys, passwords, or other sensitive data.","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fzeroize-audit\u002FSKILL.md",[166],{"categoryNo":94,"categoryName":95,"taxonomyType":66,"taxonomyTypeDesc":67},[168,169,170,171,172,173,174,175,27,176,177,178,179,180,181,182,183,184,185,103],"zeroize audit","audit","write","passwords","get","project","c++","activate","assembly","read","Bash","secrets","analysis","data","flow","verification","code","rust"]