0

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://learn.microsoft.com/en-us/azure/storage/blobs/storage-blob-event-quickstart

Kishan Gupta
  • 586
  • 1
  • 5
  • 18

4 Answers4

3

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

Tom Sun - MSFT
  • 24,161
  • 3
  • 30
  • 47
  • 1
    Great. It worked. I was trying to deploy it on EAST US location which is wrong. Thank you :) – Kishan Gupta Nov 07 '17 at 15:05
  • I tested the entire thing with RequestBin tool and it worked as expected. But now when I try to change Full Endpoint URL with my web api url, azure is not accepting/saving changes. Do I need an https web api URL ? Right now I have http url – Kishan Gupta Nov 07 '17 at 19:50
  • @Tom Sun, Did you check the same example with sample WEB API? – Balanjaneyulu K May 24 '18 at 09:27
2

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 };
    }
dbarkol
  • 291
  • 2
  • 7
0

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; }
}
dbarkol
  • 291
  • 2
  • 7
0

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

Josh Mouch
  • 3,480
  • 1
  • 37
  • 34