Publishing to an Event Grid topic from .Net
If you're using Azure's Event Grid and want to publish a custom event to an Event Grid topic, you need to do so via the REST API.
To make this easier, here's a class that'll make this a one-line operation in your code:
Update
Since posting this a reader has brought to my attention issues with using HttpClient as a disposable object. Thank you!!
The implementation, therefore, might be a bit different than what was originally posted here in Nov 2017. But it's all for the better I promise! 😃
class EventGridObject
{
private static readonly HttpClient _httpClient = new HttpClient();
private readonly Uri _endpoint;
private readonly string _sasKey;
public EventGridObject(string topicEndpoint, string sasKey, string subject, string eventType, string id = null, DateTime? eventTime = null) : this(new Uri(topicEndpoint), sasKey, subject, eventType, id, eventTime) { }
public EventGridObject(Uri topicEndpoint, string sasKey, string subject, string eventType, string id = null, DateTime? eventTime = null)
{
_endpoint = topicEndpoint ?? throw new ArgumentNullException(nameof(topicEndpoint));
_sasKey = !string.IsNullOrWhiteSpace(sasKey) ? sasKey : throw new ArgumentNullException(nameof(sasKey));
Id = string.IsNullOrWhiteSpace(id) ? Guid.NewGuid().ToString() : id;
Subject = !string.IsNullOrWhiteSpace(subject) ? subject : throw new ArgumentNullException(nameof(subject));
EventType = !string.IsNullOrWhiteSpace(eventType) ? eventType : throw new ArgumentNullException(nameof(eventType));
EventTime = eventTime ?? DateTime.UtcNow;
// https://byterot.blogspot.co.uk/2016/07/singleton-httpclient-dns.html
System.Net.ServicePointManager.FindServicePoint(_endpoint).ConnectionLeaseTimeout = (int)TimeSpan.FromMinutes(1).TotalMilliseconds;
}
[JsonProperty(@"data")]
public object Data { get; set; }
[JsonProperty(@"id")]
public string Id { get; }
[JsonProperty(@"subject")]
public string Subject { get; }
[JsonProperty(@"eventType")]
public string EventType { get; }
[JsonProperty(@"eventTime")]
public DateTime EventTime { get; }
public async Task<HttpResponseMessage> SendAsync()
{
if (_httpClient.DefaultRequestHeaders.Contains(@"aeg-sas-key"))
_httpClient.DefaultRequestHeaders.Remove(@"aeg-sas-key");
_httpClient.DefaultRequestHeaders.Add(@"aeg-sas-key", _sasKey);
return await _httpClient.PostAsJsonAsync(_endpoint, new[] { this });
}
}
and you use it like this:
await new EventGridObject(@"https://<grid topic>.westus2-1.eventgrid.azure.net/api/events", @"Yo58SQ...=", @"my/subject/data/goes/here", @"myEventType")
{
Data = new
{
myproperty1 = @"value1",
myprop2 = variable2,
queuedTime = DateTime.UtcNow
}
}.SendAsync();