Let’s hookup with ASP.NET Webhooks Preview

Webhook – A simple HTTP POST based pub/sub mechanism between web applications or services. This is a very effective that most of the modern web applications use this in order to handle event based pub/sub.

ASP.NET WebHooks is a framework which is in the preview release; this eases the task of incorporating webhooks in ASP.NET applications. It provides some predefined clients to subscribe events from, like Instagram, GitHub and others. It also provides a way to setup our custom ASP.NET web applications to send webhook notifications to the subscribed clients and prepare the clients to receive the webhook notifications. See the below URL for the more information.

https://github.com/aspnet/WebHooks

How WebHooks work and the structure of the ASP.NET WebHook Framework

Webhooks are simple HTTP POST based pub/sub.

Webhooks has the following structure.

  • The web application/service which publishes the events should provide an interface for the subscribers to register for the webhooks.
  • Subscribers select the events they want to subscribe to, submit the callback URL to be notified along with other optional parameters. Security keys are most common among the other optional parameters.
  • The publisher will persist the subscriber details.
  • When the event occurs publisher notifies all the eligible subscribers by triggering POST request to the callback back along with the event data.

The above 4 steps are the most vital steps of a working webhook. Let’s see how ASP.NET Webhooks implement this.

As of this writing ASP.NET Webhooks are in preview and nugget packages also in the preview release.

The support for sending WebHooks is provided by the following Nuget packages:

  • Microsoft.AspNet.WebHooks.Custom: This package provides the core functionality for adding WebHook support to your ASP.NET project. The functionality enables users to register WebHooks using a simple pub/sub model and for your code to send WebHooks to receivers with matching WebHook registrations.
  • Microsoft.AspNet.WebHooks.Custom.AzureStorage This package provides optional support for persisting WebHook registrations in Microsoft Azure Table Storage.
  • Microsoft.AspNet.WebHooks.Custom.Mvc This package exposes optional helpers for accessing WebHooks functionality from within ASP.NET MVC Controllers. The helpers assist in providing WebHook registration through MVC controllers as well as creating event notification to be sent to WebHook registrants.
  • Microsoft.AspNet.WebHooks.Custom.Api This package contains an  optional set of ASP.NET Web API Controllers for managing filters and registrations through a REST-style interface.

ASP.NET Webhooks works well in Web API and it has the Azure Table Storage provider for persisting the publisher metadata and event data.

Please go through this article for the detailed information

What is missing

According to the article, webhooks are delivered to the users based on authorization. So ASP.NET webhooks store the information of the subscriber along with the user information. This helps the ASP.NET webhooks to publish the event to the right subscriber.

For example, 2 users have subscribed to the same event.

User Id Event Callback URL
Thuru PhotoAdded https://thuru.net/api/webhooks/in/content
Bob PhotoAdded http://bob.net/api/hooks/incoming/photo

ASP.NET Webhooks requires the subscribers to login to the application or the REST service in order to subscribe the events.

So when the event is triggered based on the logged in user the POST request is made to the right client. ASP.NET webhooks use user based notifications. Is there any limitation in this?

Yes, consider a scenario – where you have an application with multiple customers. Each customer has many users. And the admin of one customer wants subscribe to the PhotoAdded event as above. Her intention is to be notified whenever any of her users add a photo. So if she registers for a webhook by logging in using her credentials, she will get the notifications only when she adds a photo, because ASP.NET webhooks by default provide user based notifications. Also we can’t register this event in the global level with no authentication, the she will be notified when users of the other customers add a photo.

I hope ASP.NET webhook will provide a way to customize the notification. As of now NotifyAsync is a static extension method to which the overriding is not possible.

Advertisement

Custom Authorization Filter returns 200 OK during authorization failure in Web API / MVC

This is a very specific and a quick post. In Web APIs sometimes we need to implement custom authorization filter which is extended from AuthorizeAttribute class, this is mainly useful in implementing authorization.

The below code shows how to implement an admin authorization in claims based authentication using ClaimsIdentity

The above code works perfectly in controllers and actions. If you pass ‘true’ to IsAdmin only the authentication requests with the claim IsAdmin true can access the respective controllers or actions.

So when a user who is not an admin tries to access controller / action decorated with the above attribute the client should receive a 401 (Unauthorized) / 403 (Forbidden) reply.

The Problem

But the in Web API you will get a response with status code 200 (OK) with the response body with the following message.

This is not a desirable behavior mainly in APIs because when you make a request from AJAX using any Javascript library, there’s a high probability that they would treat the request as success. You should in cooperate specific client logic to detect this and read the response body JSON message.

And also as API developers we do not prefer this default behavior.

The Solution

The solution is very simple, yet I thought to write a blog on this because in the Internet most of the posts say that this behavior cannot be altered from the API side. But API developers have full control over this behavior. Simply override the HandleUnauthorizedRequest method of the AuthorizeAttribute class.

Now you will get 403 error code as expected with the custom message provided in the Content in the response body.

If it is an MVC application you could do a redirection to the login page.

HttpResponseMessage vs IHttpActionResult

In Web API 2 IHttpActionResult is introduced. Read this post which explains the Web API 2 response types and the benefits of IHttpActionResult

Assuming you’ve read the above article it is recommended to use IHttpActionResult.

Apart from the benefits of clean code and unit testing the main design argument of using IHttpActionResult is the single responsibility principle; stating that actions have the responsibility of serving the HTTP requests and should not involve in creating the HTTP response messages. This argument makes sense, but keeping this aside if we look at the implementation of IHttpActionResult it calls the ExecuteAsync method to create the HttpResponseMessage object.

But overall it is new, easy to perform unit testing and a recommended practice to use IHttpActionResult. I personally prefer IHttpActionResult due to clean code and the ability to write neat unit tests.

Still HttpResponseMessage provides more control over the HTTP response message sent across the wire, do we have that control in IHttpActionResult especially the HTTP response message creation is hidden from us.

Yes you can get the full control. Because in the above article it’s mentioned that ExecuteAsync method is called in the pipeline in constructing the HTTP response. So the solution is simple we should have a custom type which implements IHttpActionResult interface and provide the logic for for creating the HttpResponseMessage object.

This github repo has the code for a generic type which implements IHttpActionResult. Which you can use or extend; in the sample I have provided how to implement caching in the response header.

The main class is CacheableHttpActionResult<T>

How to create Cascading Dropdowns in Angular JS using Web API

Angular JS is one of the famous and a ‘WoW’ making Javascript frameworks available. https://angularjs.org/ has plenty of learning resources for Angular JS. This post shows how to create cascading drop downs using Angular JS whilst showing the use of other basic features of Angular JS.

Angular JS relies heavily on angular directives which HTML extended attributes with prefix of ng-

The following sample shows a simple web application developed using Angular JS and Web API. I used the AdventureWorks2012LT database and a Web API 2. UI has two dropdowns, first one shows the product categories and when a category is selected the second one shows the products for that particular category.

http://localhost/ADLTService/api/productcategory – to get the product categories

http://localhost/ADLTService/api/productforcategory/{id} – to get the products for a category id.

Create a simple HTML project and add Angular from NuGet. The below code shows the app script.

thuruinhttp.wordpress.com

The below is my HTML

thuruinhttp.wordpress.com

ng-repeat directive loops through the collection and creates the <options> tag for us. ng-model binds the value to the parameter in ng-change event. Here the name should be identical. The rest Angular knows how to interpret. Cascading drop down simple as that. You can also use ng-options as a directive for the <select> for more details refer this article.

Working Model.

angular cascading drop down

How to enable sessions in Web API

Web API does not support native HTTP sessions. And it’s the nature of Web API, but there might be times you need HTTP sessions which resembles your bad design. Because a service framework should not support HTTP sessions as it should be a stateless element. So why do we need sessions in Web API ? I think you should not use sessions in Web API in production; eliminate HTTP sessions completely.

So the answer for the question why do we need sessions in Web API is, just to show how you can enable them. Silly though but you can use this in developing some POC and quick functional demos. Never use sessions in Web API because Web API is designed to be stateless.

First we should implement a ControllerHandler which is capable of handling sessions. In order make our ControllerHandler handle sessions we should implement IRequiresSessionState interface as well. Look at the below code.

   1: public class SessionableControllerHandler : HttpControllerHandler, IRequiresSessionState

   2: {

   3:     public SessionableControllerHandler(RouteData routeData) 

   4:         : base(routeData)

   5:     {

   6:  

   7:     }

   8: }

The next step is to create a RouteHandler as a wrapper to the ControllerHandler we created, this is because when registering routes in the RouteTable we can pass RouteHandler types not ControllerHandler types. Look at the below code for the custom RouteHandler.

   1: public class SessionStateRouteHandler : IRouteHandler

   2: {

   3:     public IHttpHandler GetHttpHandler(RequestContext requestContext)

   4:     {

   5:         return new SessionableControllerHandler(requestContext.RouteData);

   6:     }

   7: }

Then finally we have to register our RouteHandler in the RouteTable

   1: RouteTable.Routes.MapHttpRoute(

   2:     name: "DefaultApi",

   3:     routeTemplate: "api/{controller}/{id}",

   4:     defaults: new { id = RouteParameter.Optional }

   5: ).RouteHandler = new SessionStateRouteHandler();

In order to make our custom route to be used we need to put it on top of other route registrations.