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