You are on page 1of 25


NET WebHooks Documentation



Sep 12, 2016


1 Overview of ASP.NET WebHooks 3

1.1 WebHooks Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 WebHooks Processing Pipeline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2 Source Code and Nugets 7

2.1 Nuget Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

3 Receiving WebHooks 9
3.1 WebHook Receivers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.2 Processing WebHooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.3 Receiver Dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

4 Sending WebHooks 15
4.1 WebHook Senders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

5 Diagnostics 17
5.1 Logging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
5.2 Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

6 Contribute 21

ASP.NET WebHooks Documentation, Release

Note: This documentation is a work in progress. Topics marked with a are placeholders that have not been written
yet. You can track the status of these topics through our public documentation issue tracker. Learn how you can
contribute on GitHub.

Contents 1
ASP.NET WebHooks Documentation, Release

2 Contents

Overview of ASP.NET WebHooks

WebHooks is a lightweight HTTP pattern providing a simple pub/sub model for wiring together Web APIs and SaaS
services. When an event happens in a service, a notification is sent in the form of an HTTP POST request to registered
subscribers. The POST request contains information about the event which makes it possible for the receiver to act
Because of their simplicity, WebHooks are already exposed by a large number of services including Dropbox, GitHub,
Bitbucket, MailChimp, PayPal, Slack, Stripe, Trello, and many more. For example, a WebHook can indicate that a file
has changed in Dropbox, or a code change has been committed in GitHub, or a payment has been initiated in PayPal,
or a card has been created in Trello. The possibilities are endless!
Microsoft ASP.NET WebHooks makes it easier to both send and receive WebHooks as part of your ASP.NET appli-
• On the receiving side, it provides a common model for receiving and processing WebHooks from any number of
WebHook providers. It comes out of the box with support for Dropbox, GitHub, Bitbucket, MailChimp, PayPal,
Pusher, Salesforce, Slack, Stripe, Trello, and WordPress but it is easy to add support for more.
• On the sending side it provides support for managing and storing subscriptions as well as for sending event
notifications to the right set of subscribers. This allows you to define your own set of events that subscribers can
subscribe to and notify them when things happens.
The two parts can be used together or apart depending on your scenario. If you only need to receive WebHooks from
other services then you can use just the receiver part; if you only want to expose WebHooks for others to consume,
then you can do just that.
The code targets ASP.NET Web API 2 and ASP.NET MVC 5 and is available as OSS on GitHub.

1.1 WebHooks Overview

WebHooks is a pattern which means that it varies how it is used from service to service but the basic idea is the same.
You can think of WebHooks as a simple pub/sub model where a user can subscribe to events happening elsewhere.
The event notifications are propagated as HTTP POST requests containing information about the event itself.
Typically the HTTP POST request contains a JSON object or HTML form data determined by the WebHook sender
including information about the event causing the WebHook to trigger. For example, an example of a WebHook POST
request body from GitHub looks like this as a result of a new issue being opened in a particular repository:
"action": "opened",
"issue": {
"url": "",
"number": 1347,

ASP.NET WebHooks Documentation, Release

"repository": {
"id": 1296269,
"full_name": "octocat/Hello-World",
"owner": {
"login": "octocat",
"id": 1
"sender": {
"login": "octocat",
"id": 1,

To ensure that the WebHook is indeed from the intended sender, the POST request is secured in some way and then
verified by the receiver. For example, GitHub WebHooks includes an X-Hub-Signature HTTP header with a hash of
the request body which is checked by the receiver implementation so you don’t have to worry about it.
The WebHook flow generally goes something like this:
• The WebHook sender exposes events that a client can subscribe to. The events describe observable changes to
the system, for example that a new data item has been inserted, that a process has completed, or something else.
• The WebHook receiver subscribes by registering a WebHook consisting of four things:
1. A URI for where the event notification should be posted in the form of an HTTP POST request;
2. A set of filters describing the particular events for which the WebHook should be fired;
3. A secret key which is used to sign the HTTP POST request;
4. Additional data which is to be included in the HTTP POST request. This can for example be additional
HTTP header fields or properties included in the HTTP POST request body.
• Once an event happens, the matching WebHook registrations are found and HTTP POST requests are submitted.
Typically, the generation of the HTTP POST requests are retried several times if for some reason the recipient
is not responding or the HTTP POST request results in an error response.

1.2 WebHooks Processing Pipeline

The Microsoft ASP.NET WebHooks processing pipeline for incoming WebHooks looks like this:

4 Chapter 1. Overview of ASP.NET WebHooks

ASP.NET WebHooks Documentation, Release

The two key concepts here are Receivers and Handlers:

• Receivers are responsible for handling the particular flavor of WebHook from a given sender and for enforcing
security checks to ensure that the WebHook request indeed is from the intended sender.
• Handlers are typically where user code runs processing the particular WebHook.
In the following nodes these concepts are described in more details.

1.2. WebHooks Processing Pipeline 5

ASP.NET WebHooks Documentation, Release

6 Chapter 1. Overview of ASP.NET WebHooks


Source Code and Nugets

Microsoft ASP.NET WebHooks is part of the Microsoft ASP.NET family of modules and is hosted as an Open Source
Project on GitHub. This means that we accept contributions, but please look at the Contribution Guidelines before
submitting a pull request.
This online documentation which you are reading now is also hosted as Open Source on GitHub and also accepts

2.1 Nuget Packages

Microsoft ASP.NET WebHooks is also available as preview Nuget packages which means that you have to select the
Preview flag in Visual Studio in order to see them.
The Nuget packages are devided into three parts:
• Common: A common package that is shared between senders and receivers.
• Sender: A set of packages supporting sending your own WebHooks to others. The functionality for sending
WebHooks is described in more detail in Sending WebHooks.
• Receivers: A set of packages supporting receiving WebHooks from others. The functionality for receiving
WebHooks is described in more detail in Receiving WebHooks.

ASP.NET WebHooks Documentation, Release

8 Chapter 2. Source Code and Nugets


Receiving WebHooks

Note: This documentation is a work in progress. Topics marked with a are placeholders that have not been written
yet. You can track the status of these topics through our public documentation issue tracker. Learn how you can
contribute on GitHub.

3.1 WebHook Receivers

Receiving WebHooks depends on who the sender is. Sometimes there are additional steps registering a WebHook
verifying that the subscriber is really listening. Some WebHooks provide a push-to-pull model where the HTTP POST
request only contains a reference to the event information which is then to be retrieved independently. Often the
security model varies quite a bit.
The purpose of Microsoft ASP.NET WebHooks is to make it both simpler and more consistent to wire up your API
without spending a lot of time figuring out how to handle any particular variant of WebHooks.
A WebHook receiver is responsible for accepting and verifying WebHooks from a particular sender. A WebHook
receiver can support any number of WebHooks, each with their own configuration. For example, the GitHub WebHook
receiver can accept WebHooks from any number of GitHub repositories.

3.1.1 WebHook Receiver URIs

By installing Microsoft ASP.NET WebHooks you get a general WebHook controller which accepts WebHook requests
from an open-ended number of services. When a request arrives, it picks the appropriate receiver that you have
installed for handling a particular WebHook sender.
The URI of this controller is the WebHook URI that you register with the service and is of the form:

For security reasons, many WebHook receivers require that the URI is an https URI and in some cases it must also
contain an additional query parameter which is used to enforce that only the intended party can send WebHooks to the
URI above.
The <receiver> component is the name of the receiver, for example github or slack.
The {id} is an optional identifier which can be used to identify a particular WebHook receiver configuration. This
can be used to register N WebHooks with a particular receiver. For example, the following three URIs can be used to
register for three independent WebHooks:

ASP.NET WebHooks Documentation, Release


3.1.2 Installing a WebHook Receiver

To receive WebHooks using Microsoft ASP.NET WebHooks, you first install the Nuget package for the Web-
Hook provider or providers you want to receive WebHooks from. The Nuget packages are named Mi-
crosoft.AspNet.WebHooks.Receivers.* where the last part indicates the service supported. For example
Microsoft.AspNet.WebHooks.Receivers.GitHub provides support for receiving WebHooks from GitHub and Mi-
crosoft.AspNet.WebHooks.Receivers.Custom provides support for receiving WebHooks generated by ASP.NET Web-
Out of the box you can find support for Dropbox, GitHub, MailChimp, PayPal, Pusher, Salesforce, Slack, Stripe,
Trello, and WordPress but it is possible to support any number of other providers.

3.1.3 Configuring a WebHook Receiver

WebHook Receivers are configured through the IWebHookReceiverConfig inteface and particular implementations of
that interface can be registered using any dependency injection model. The default implementation uses Application
Settings which can either be set in the Web.config file, or, if using Azure Web Apps, can be set through the Azure

The format for Application Setting keys is as follows:


The value is a comma-separated list of values matching the {id} values for which WebHooks have been registered, for
MS_WebHookReceiverSecret_GitHub = <secret1>, 12345=<secret2>, 54321=<secret3>

10 Chapter 3. Receiving WebHooks

ASP.NET WebHooks Documentation, Release

3.1.4 Initializing a WebHook Receiver

WebHook Receivers are initialized by registering them, typically in the WebApiConfig static class, for example:
namespace WebHookReceivers
public static class WebApiConfig
public static void Register(HttpConfiguration config)
// Web API configuration and services

// Web API routes


name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }

// Load receivers

3.2 Processing WebHooks

Once WebHooks requests has been validated by a WebHook receiver, it is ready to be processed by user code. This is
where handlers come in. Handlers derive from the IWebHookHandler interface but typically uses the WebHookHan-
dler class instead of deriving directly from the interface.
A WebHook request can be processed by one or more handlers. Handlers are called in order based on their respective
Order property going from lowest to highest where Order is a simple integer (suggested to be between 1 and 100):

A handler can optionally set the Response property on the WebHookHandlerContext which will lead the processing to
stop and the response to be sent back as the HTTP response to the WebHook. In the case above, Handler C won’t get
called because it has a higher order than B and B sets the response.
Setting the response is typically only relevant for WebHooks where the response can carry information back to the
originating API. This is for example the case with Slack WebHooks where the response is posted back to the channel

3.2. Processing WebHooks 11

ASP.NET WebHooks Documentation, Release

where the WebHook came from. Handlers can set the Receiver property if they only want to receive WebHooks from
that particular receiver. If they don’t set the receiver they are called for all of them.
One other common use of a response is to use a 410 Gone response to indicate that the WebHook no longer is active
and no further requests should be submitted.
By default a handler will be called by all WebHook receivers. However, if the Receiver property is set to the name of
a handler then that handler will only receive WebHook requests from that receiver.

3.2.1 Processing a WebHook

When a handler is called, it gets a WebHookHandlerContext containing information about the WebHook request. The
data, typically the HTTP request body, is available from the Data property.
The type of the data is typically JSON or HTML form data, but it is possible to cast to a more specific type if desired.
For example, the custom WebHooks generated by ASP.NET WebHooks can be cast to the type CustomNotifications
as follows:
public class MyWebHookHandler : WebHookHandler
public MyWebHookHandler()
this.Receiver = "custom";

public override Task ExecuteAsync(string generator, WebHookHandlerContext context)

CustomNotifications notifications = context.GetDataOrDefault<CustomNotifications>();
foreach (var notification in notifications.Notifications)
return Task.FromResult(true);

3.2.2 Queued Processing

Most WebHook senders will resend a WebHook if a response is not generated within a handful of seconds. This means
that your handler must complete the processing within that time frame in order not for it to be called again.
If the processing takes longer, or is better handled separately then the WebHookQueueHandler can be used to submit
the WebHook request to a queue, for example Azure Storage Queue.
An outline of a WebHookQueueHandler implementation is provided here:
public class QueueHandler : WebHookQueueHandler
public override Task EnqueueAsync(WebHookQueueContext context)

// Enqueue WebHookQueueContext to your queuing system of choice

return Task.FromResult(true);

12 Chapter 3. Receiving WebHooks

ASP.NET WebHooks Documentation, Release

3.3 Receiver Dependencies

Microsoft ASP.NET WebHooks is designed with dependency injection in mind. Most dependencies in the system can
be replaced with alternative implementations using a dependency injection engine.
Please see DependencyScopeExtensions for a list of receiver dependencies. If no dependency has been registered, a
default implementation is used. Please see ReceiverServices for a list of default implementations.

3.3. Receiver Dependencies 13

ASP.NET WebHooks Documentation, Release

14 Chapter 3. Receiving WebHooks


Sending WebHooks

Note: This documentation is a work in progress. Topics marked with a are placeholders that have not been written
yet. You can track the status of these topics through our public documentation issue tracker. Learn how you can
contribute on GitHub.

4.1 WebHook Senders

Please see the blog Sending WebHooks with ASP.NET WebHooks Preview for more details.

ASP.NET WebHooks Documentation, Release

16 Chapter 4. Sending WebHooks



Note: This documentation is a work in progress. Topics marked with a are placeholders that have not been written
yet. You can track the status of these topics through our public documentation issue tracker. Learn how you can
contribute on GitHub.

5.1 Logging

Microsoft ASP.NET WebHooks uses logging as a way of reporting issues and problems. By default logs are written
using System.Diagnostics.Trace where they can be manged using Trace Listeners like any other log stream.
When deploying your Web Application as an Azure Web App, the logs are automatically picked up and can be managed
together with any other System.Diagnostics.Trace logging. For details, please see Enable diagnostics logging for web
apps in Azure App Service
In addition, logs can be obtained straight from inside Visual Studio as described in Troubleshoot a web app in Azure
App Service using Visual Studio.

5.1.1 Redirecting Logs

Instead of writing logs to System.Diagnostics.Trace, it is possible to provide an alternate logging implementation

that can log directly to a log manager such as Log4Net and NLog. Simply provide an implementation of ILogger
and register it with a dependency injection engine of your choice and it will get picked up by Microsoft ASP.NET
WebHooks. Please see Dependency Injection in ASP.NET Web API 2 for details.

5.2 Debugging

5.2.1 Debugging in Azure

To debug your Web Application while running in Azure, please see the tutorial Troubleshoot a web app in Azure App
Service using Visual Studio.

ASP.NET WebHooks Documentation, Release

5.2.2 Debugging with Source and Symbols

In addition to debugging your own code, it is possible to debug directly into Microsoft ASP.NET WebHooks, and in
fact all of .NET. This works regardless of whether you debug locally or remotely. First, configure Visual Studio to find
the source and symbols by going to Debug and then Options and Settings. Set the options like this:

Then add a link to for downloading the source and symbols. Go to the Symbols tab of the menu
above and add the following as a symbol location:

In addition, make sure that the cache directory has a short name; otherwise the file names can get too long which will
cause the symbols to not load. A sample path is:

The settings should look similar to this:

18 Chapter 5. Diagnostics
ASP.NET WebHooks Documentation, Release

5.2. Debugging 19
ASP.NET WebHooks Documentation, Release

20 Chapter 5. Diagnostics


The documentation on this site is the handiwork of our many contributors.

We accept pull requests! But you’re more likely to have yours accepted if you follow these guidelines:
1. Read
2. Follow the ASP.NET Docs Style Guide