0
votes

I am new to Azure Event Grid and Webhooks.

How can I bind my .net mvc web api application to Microsoft Azure Event Grid?

In short I want, whenever a new file is added to blob storage, Azure Event grid should notify my web api application.

I tried following article but no luck https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-event-quickstart

4

4 Answers

3
votes

How can I bind my .net mvc web api application to Microsoft Azure Event Grid? In short I want, whenever a new file is added to blob storage, Azure Event grid should notify my web api application.

I do a demo for that, it works correctly on my side. You could refer to the following steps:

1.Create a demo RestAPI project just with function

 public string Post([FromBody] object value) //Post
 {
      return $"value:{value}";
 }

2.If we want to intergrate azure storage with Azure Event Grid, we need to create a blob storage account in location West US2 or West Central US. More details could refer to the screen shot.

enter image description here

2.Create Storage Accounts type Event Subscriptions and bind the custom API endpoint

enter image description here

enter image description here

3.Upload the blob to the blob storage and check from the Rest API.

enter image description here

2
votes

You can accomplish this by creating an custom endpoint that will subscribe to the events published from Event Grid. The documentation you referenced uses Request Bin as a subscriber. Instead create a Web API endpoint in your MVC application to receive the notification. You'll have to support the validation request just to make you have a valid subscriber and then you are off and running.

Example:

    public async Task<HttpResponseMessage> Post()
    {
        if (HttpContext.Request.Headers["aeg-event-type"].FirstOrDefault() == "SubscriptionValidation")
        {
            using (var reader = new StreamReader(Request.Body, Encoding.UTF8))
            {
                var result = await reader.ReadToEndAsync();
                var validationRequest = JsonConvert.DeserializeObject<GridEvent[]>(result);
                var validationCode = validationRequest[0].Data["validationCode"];

                var validationResponse = JsonConvert.SerializeObject(new {validationResponse = validationCode});
                return new HttpResponseMessage
                {
                    StatusCode = HttpStatusCode.OK, 
                    Content = new StringContent(validationResponse)
                };                       
            }
        }

        // Handle normal blob event here

        return new HttpResponseMessage { StatusCode = HttpStatusCode.OK };
    }
0
votes

Below is an up-to-date sample of how you would handle it with a Web API. You can also review and deploy a working sample from here: https://github.com/dbarkol/azure-event-grid-viewer

    [HttpPost]
    public async Task<IActionResult> Post()
    {
        using (var reader = new StreamReader(Request.Body, Encoding.UTF8))
        {
            var jsonContent = await reader.ReadToEndAsync();

            // Check the event type.
            // Return the validation code if it's 
            // a subscription validation request. 
            if (EventTypeSubcriptionValidation)
            {
                var gridEvent =
                    JsonConvert.DeserializeObject<List<GridEvent<Dictionary<string, string>>>>(jsonContent)
                        .First();


                // Retrieve the validation code and echo back.
                var validationCode = gridEvent.Data["validationCode"];
                return new JsonResult(new{ 
                    validationResponse = validationCode
                });
            }
            else if (EventTypeNotification)
            {
                // Do more here...
                return Ok();                 
            }
            else
            {
                return BadRequest();
            }
        }

    }

public class GridEvent<T> where T: class
{
    public string Id { get; set;}
    public string EventType { get; set;}
    public string Subject {get; set;}
    public DateTime EventTime { get; set; } 
    public T Data { get; set; } 
    public string Topic { get; set; }
}
0
votes

You can also use the Microsoft.Azure.EventGrid nuget package.

From the following article (credit to gldraphael): https://gldraphael.com/blog/creating-an-azure-eventgrid-webhook-in-asp-net-core/

[Route("/api/webhooks"), AllowAnonymous]
public class WebhooksController : Controller
{
    // POST: /api/webhooks/handle_ams_jobchanged
    [HttpPost("handle_ams_jobchanged")] // <-- Must be an HTTP POST action
    public IActionResult ProcessAMSEvent(
        [FromBody]EventGridEvent[] ev, // 1. Bind the request
        [FromServices]ILogger<WebhooksController> logger)
    {
        var amsEvent = ev.FirstOrDefault(); // TODO: handle all of them!
        if(amsEvent == null) return BadRequest();

        // 2. Check the eventType field
        if (amsEvent.EventType == EventTypes.MediaJobStateChangeEvent)
        {
            // 3. Cast the data to the expected type
            var data = (amsEvent.Data as JObject).ToObject<MediaJobStateChangeEventData>();

            // TODO: do your thing; eg:
            logger.LogInformation(JsonConvert.SerializeObject(data, Formatting.Indented));
        }

        // 4. Respond with a SubscriptionValidationResponse to complete the 
        // event subscription handshake.
        if(amsEvent.EventType == EventTypes.EventGridSubscriptionValidationEvent)
        {
            var data = (amsEvent.Data as JObject).ToObject<SubscriptionValidationEventData>();
            var response = new SubscriptionValidationResponse(data.ValidationCode);
            return Ok(response);
        }
        return BadRequest();
    }
}