Skip to content

Capturing SendGrid Events With ASP.NET WebAPI and Task async

Updated: at 11:18 PM

 

Problem

I’ve been using SendGrid’s API WebHooks to capture email events (Version 1).  This version sends one event at a time which has always been a pretty bad idea.  When I first did the integration a year or so ago, the only way to capture multiple events at once was to consume some proprietary non-JSON like protocol.  I declined.  They finally have upgraded the API to send standard JSON records and are going to obsolete version 1 so I need to change.  Here goes…

Send Grid Event Notification Configuration

First, you need to go into Event Notification and change to (v3) of the config.  Then, I pressed the “Test Your Integration” button while running fiddler to grab the JSON SendGrid generates (see screen shot)

image

Figure Out The JSON Structure

The generated JSON looks like this:

image

At this point, there are lots of ways to decode the JSON.  My choice is to us http://json2csharp.com, paste in my json data and it generates the classes I need to encode the JSON data into.

image

Next, I create a WebAPI controller in ASP.NET and simply have with one method for POST.  I add the above classes and then unwind the data when it comes in as follows.

The controller I build (as a guess) looks like this: (I’m leaving out what I do with the data in the foreach.  Reality is I’m going to stuff it in a database)

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using Microsoft.Ajax.Utilities;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace WebAPI.rest { public class SendGridController : ApiController { public async Task Post() { string jsonData = await Request.Content.ReadAsStringAsync(); dynamic dataList = JArray.Parse(jsonData);

        <span class="kwrd">using</span> (
            var sqlConnection =
                <span class="kwrd">new</span> SqlConnection(ConfigurationManager.ConnectionStrings[<span class="str">&quot;CodeCampSV06&quot;</span>].ConnectionString))
        {
            sqlConnection.Open();

            <span class="kwrd">foreach</span> (var rec <span class="kwrd">in</span> dataList)
            {

                <span class="kwrd">string</span> eventName = (<span class="kwrd">string</span>) rec[<span class="str">&quot;event&quot;</span>] ?? <span class="str">&quot;&quot;</span>;
                <span class="kwrd">string</span> email = (<span class="kwrd">string</span>) rec[<span class="str">&quot;email&quot;</span>] ?? <span class="str">&quot;&quot;</span>;
                <span class="kwrd">string</span> category = <span class="str">&quot;&quot;</span>;
                <span class="rem">//string category = rec.category != null &amp;&amp; rec.category.Count &gt; 0 ? rec.category[0] : &quot;&quot;;</span>
                <span class="kwrd">string</span> url =  (<span class="kwrd">string</span>) rec[<span class="str">&quot;url&quot;</span>] ?? <span class="str">&quot;&quot;</span>;
                <span class="kwrd">string</span> generalType =  (<span class="kwrd">string</span>) rec[<span class="str">&quot;type&quot;</span>] ?? <span class="str">&quot;&quot;</span>;
                <span class="kwrd">string</span> reason =  (<span class="kwrd">string</span>) rec[<span class="str">&quot;reason&quot;</span>] ?? <span class="str">&quot;&quot;</span>;
                <span class="kwrd">string</span> statusString = (<span class="kwrd">string</span>) rec[<span class="str">&quot;status&quot;</span>] ?? <span class="str">&quot;&quot;</span>;
                <span class="kwrd">string</span> attempt =(<span class="kwrd">string</span>) rec[<span class="str">&quot;attempt&quot;</span>] ?? <span class="str">&quot;&quot;</span>;
                <span class="kwrd">string</span> responseString = (<span class="kwrd">string</span>)rec[<span class="str">&quot;response&quot;</span>] ?? <span class="str">&quot;&quot;</span>;
                <span class="kwrd">string</span> emailpkid = (<span class="kwrd">string</span>)rec[<span class="str">&quot;emailpkid&quot;</span>] ?? <span class="str">&quot;&quot;</span>;

                 <span class="rem">// do something with the data!</span>
                
            }
        }
    }
}

}

 

Testing The WebAPI Rest Controller

To test the controller, I need to simulate a call that SendGrid will be issuing to me.  I do that by using fiddler to compose a new query.  Below is a screen shot of what that composed query looks like on my system.  Notice I’ve set it to POST and I’ve pasted in the content JSON that SendGrid will be sending me (got it from the test post above)

image

You can now see, when I press “Execute in fiddler” while Visual Studio is running in debug mode, my data is all coming in as I expect.

image

 

That’s it! basically we’ve done it.  HTHs.  We’ve build a WebAPI controller using async to capture data coming in as a JSON payload.