MAC vendor lookup REST API

The RC version of ASP.NET MVC 4 was released some weeks ago with a lot of new features which you can read at its homepage http://www.asp.net/mvc/mvc4. One of the most interesting one is ASP.NET Web API which provides an interface to make a RESTful web service and can be accessed from any devices like computer, smart phone, tables… through HTTP protocol. REST (Representational State Transfer) has emerged over the past few year as a predominant design model for web service thanks to its simpler style in comparison to SOAP or WSDL. For example, my colleague has always complained about our SOAP web service when he consumes it on Android platform with plenty of XML parsing and DOM manipulation.

RESTful web service is much more simpler. It can be activated by a GET request or by passing plain XML over POST and gives respond with non-SOAP content such as XML, JSON or any predefined format supported by consumer. A RESTful service uses 4 HTTP methods to implement CRUD actions in database.
GET: List all members of collection or details of a member in collection.
PUT: Update the entire collection with another collection or update member of collection with other one.
POST: Create a new item in the collection. The new entry’s URL is assigned automatically and is usually returned by the operation.
DELETE: Delete the entire collection or member in collection.

Maybe you’ll ask why we need ASP.NET Web API when we already have WebHttpBinding in WCF which also supports RESTful service. Let’s say, WCF 4 does support HTTP service but it wasn’t perfect. Not all kinds of request can be easily consumed (let’s try to post some HTML form data to its service), the overuse of CLR attributes to define contract is terrible and the configuration with endpoint to make it work is a nightmare for any programmer or IT administrator. Even after all of these things we really don’t take advantage of HTTP protocol. Therefore ASP.NET Web API comes to market as a rich inter-operable and resource oriented protocol. It uses properly URIs, HTTP header and HTTP body to host a real RESTful web service.

Create a RESTful web service with ASP.NET Web API is very simple. You can find at homepage above a lot of valuable tutorials there. In this post I would like to introduce my small application using ASP.NET Web API. That is MAC Vendor API application

http://macproviderapi.apphb.com/

This is a simple application which help you to find out who is the vendor of a MAC address. At the homepage of the service you can test it by giving any correct MAC address, you’ll receive its vendor back.

MAC vendor REST API test

This test will call a RESTful service running behind it and use AJAX to update homepage with name of vendor. This service is free and you can consume it if you want. However to protect it from flooding by hacker, I apply a simply authentication process. After registering, in your settings section you’ll your API key

MAC vendor REST API

This API key is unique for each user. Using it in your HTTP GET request of this format to get vendor of any MAC address

http://macproviderapi.apphb.com/api/macs/{YOUR_API_KEY}/{QUERIED_MAC_ADDRESS}

It can’t be simpler than that. We can consume a web service just by calling a URL with appropriate parameters and use it on any platform because it is only raw HTTP message.

Query vendor of MAC address

As you can see, the vendor is given back in a JSON string which can be consumed by any platform in any programming language. If you use wrong API key, you’ll get an exception of Unauthorized back in response header and blank string as result

Unauthorized when using wrong API key

In case that the format of MAC address/API key is wrong, you’ll receive a blank string with header of HttpStatusCode.NotAcceptable. The combination of HTTP header and body describe exactly what is going on with service in any request.

That’s all about the service. Just one more small thing I found when I made this service. It is relevant to Ninject and RC version of ASP.NET MVC 4. Maybe you get this error:

‘System.Web.Http.HttpConfiguration’ does not contain a definition for ‘ServiceResolver’ and no extension method ‘ServiceResolver’ accepting a first argument of type ‘System.Web.Http.HttpConfiguration’ could be found (are you missing a using directive or an assembly reference?)

This error is itself already obvious that there is no property ServiceResolver of HttpConfiguration more in RC version. To solve this error just apply this listing in your code

 public class NinjectControllerFactory : DefaultControllerFactory
{
	private IKernel ninjectKernel;

	public NinjectControllerFactory()
	{
		ninjectKernel = new StandardKernel();
		AddBindings();
		GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(ninjectKernel);
	}

	protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
	{
		return controllerType == null ? null : (IController)ninjectKernel.Get(controllerType);
	}

	private void AddBindings()
	{
		ninjectKernel.Bind<IPathMapper>().To<ServerPathMapper>();
	}
}



public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
{
	private IKernel ninjectKernel;

	public NinjectDependencyResolver(IKernel kernel)
		: base(kernel)
	{
		this.ninjectKernel = kernel;
	}

	public IDependencyScope BeginScope()
	{
		return new NinjectDependencyScope(ninjectKernel.BeginBlock());
	}
}

public class NinjectDependencyScope : IDependencyScope
{
	private IResolutionRoot resolver;

	internal NinjectDependencyScope(IResolutionRoot resolver)
	{
		Contract.Assert(resolver != null);

		this.resolver = resolver;
	}

	public void Dispose()
	{
		IDisposable disposable = resolver as IDisposable;
		if (disposable != null)
			disposable.Dispose();

		resolver = null;
	}

	public object GetService(Type serviceType)
	{
		if (resolver == null)
			throw new ObjectDisposedException("this", "This scope has already been disposed");

		return resolver.TryGet(serviceType);
	}

	public IEnumerable<object> GetServices(Type serviceType)
	{
		if (resolver == null)
			throw new ObjectDisposedException("this", "This scope has already been disposed");

		return resolver.GetAll(serviceType);
	}
}

protected void Application_Start()
{
	AreaRegistration.RegisterAllAreas();

	FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
	RouteConfig.RegisterRoutes(RouteTable.Routes);
	BundleConfig.RegisterBundles(BundleTable.Bundles);
	ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
}

One thought on “MAC vendor lookup REST API”

Leave a Reply

Your email address will not be published. Required fields are marked *