In-Depth

Implementing Binary JSON in ASP.NET Web API 2.1

Visual Studio 2013 came with a new version of Web API. The Web API 2.1 update includes a host of new features, including support for Binary JSON. Learn how to leverage BSON by building a Web API 2.1 service.

The Web API framework allows developers to quickly create services using MVC-like conventions. It offers the flexibility of creating REST style services, and serving up data in a variety of formats, including the newly supported Binary JSON (BSON) format. This article will focus on building a Web API 2.1 service utilizing the new BSON Media-Type Formatter.

ASP.Net Web API is a relatively new technology from Microsoft, released initially with the Microsoft .NET Framework 4.5. It allows a single Web service to communicate with various clients in various formats such as XML, JSON and OData. (I discussed the introduction of ASP.NET Web API is in a previous article). With Visual Studio 2013, Microsoft released ASP.NET Web API 2 in October 2013, followed by an update to Web API 2.1 in January 2014. Some of the new features in 2.1 include:

  • Global Error Handling
  • Attribute Routing Improvements
  • Help Page Improvements
  • IgnoreRoute Support
  • BSON Media-Type Formatter
  • Support for Async Filters
  • Query Parsing for the Client Formatting Library

BSON is a binary-encoded serialization of JSON-like objects (also known as documents) representing data structures and arrays. BSON objects consist of an ordered list of elements. Each element contains Field Name, Type and Value.

Field names are strings. Types can be any of the following:

  • string
  • integer (32-bit)
  • integer (64-bit)
  • double (64-bit)
  • date (integer number of milliseconds)
  • byte array
  • boolean
  • null
  • BSON object
  • BSON array
  • Regular expression
  • JavaScript code

The primary advantages of BSON are that it's lightweight with minimal spatial overhead, easy to parse, and efficient for encoding and decoding.

To demonstrate, I'll create a sample ASP.NET Web API 2.1 application in ASP.NET MVC 5, using Visual Studio 2013. This solution will be very similar to the one I discussed in my previous article (following the premise of building an inventory app for a used car lot), which will allow for comparison and contrast of old features to new features. I'll call it CarInventory21, to reflect version 2.1 of the ASP.NET Web API.

First, I create an ASP.NET Web Application, choosing an Empty template with MVC folders and core references, as seen in Figure 1 and Figure 2.

[Click on image for larger view.] Figure 1. Choose the ASP.NET Web Application
[Click on image for larger view.] Figure 2. Choose Empty Template with Web API Folders and Core References

Next, I add a class to the Model folder, calling it Car.cs, shown in Figure 3 and Figure 4.

[Click on image for larger view.] Figure 3. Add Class File to Models Folder
[Click on image for larger view.] Figure 4. Select Class File and Call It Car.cs

This class contains the following structure, representing each car in inventory (it's been slightly modified from its counterpart in the previous article):

public class Car
{
  public Int32 Id { get; set; }
  public Int32 Year { get; set; }
  public string Make { get; set; }
  public string Model { get; set; }
  public string Color { get; set; }       
}

Next, I add an Empty Web controller by right-clicking the Controllers folder | Add | Controller, as shown in Figure 5.

[Click on image for larger view.] Figure 5. Add Controller to Solution

Afterward, when prompted for the type of controller to scaffold, I chose an Empty controller (see Figures 6-8) for the sake of keeping the sample project thin and clutter-free.

[Click on image for larger view.] Figure 6. Choosing an Empty Web API 2 Controller
[Click on image for larger view.] Figure 7. Naming the Controller CarController
[Click on image for larger view.] Figure 8. Installing the Web API 2.1 Client Library

Like other ASP.NET MVC projects, the controller isn't required to be in the Controllers folder, but it's a good practice and is highly recommended. Unlike typical ASP.NET MVC projects that inherit from the Controller class, the ASP.NET Web API controller inherits the ApiController class.

Following the implementation from the previous article, I won't use a database but instead instantiate the records in code. I will also create two action methods within the controller: one to retrieve all car records, and the other to retrieve only a specific record using the ID field. The complete listing of Controllers\CarController.cs is shown in Listing 1.

Listing 1: Listing of Controllers\CarController.cs
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using CarInventory21.Models;  //Added manually


namespace CarInventory21.Controllers
{
  public class CarController : ApiController
  {
     
    Car[] cars = new Car[] 
    { 
      new Car { Id = 1, Year = 2012, Make = "Cheverolet", Model = "Corvette", Color = "Red" }, 
      new Car { Id = 2, Year = 2011, Make = "Ford", Model = "Mustang GT", Color = "Silver" }, 
      new Car { Id = 3, Year = 2008, Make = "Mercedes-Benz", Model = "C300", Color = "Black" } 
    };

    public IEnumerable<Car> GetAllCars()
    {
      return cars;
    }

    public IHttpActionResult GetCar(int id)
    {
      var car = cars.FirstOrDefault((c) => c.Id == id);
      if (car == null)
      {
        return NotFound();
      }
      return Ok(car);
    }
  }
    
}

Looking at other portions of the project, a WebApiConfig.cs is created in the App_Start folder of the solution by default. As the name suggests, this file is for globally configuring the ASP.NET Web API. Before configuring the solution for BSON, I first need the references for the BSON library. This is done automatically by installing the NuGet package Microsoft ASP.NET Web API 2.1 Client Library, as seen in Figure 8.

Installing the NuGet package will also require accepting the license agreement (see Figure 9).

[Click on image for larger view.] Figure 9. NuGet License Acceptance

Because I want to display only BSON, I will add the following lines at the bottom of the Register method in the App_Start\WebApiConfig.cs file:

config.Formatters.Clear();                             // Remove all other formatters
config.Formatters.Add(new BsonMediaTypeFormatter());   // Enable BSON in the Web service

These calls will first clear and remove all other formatters the ASP.NET Web API will use for responding to requests. Then it will add a new instance of the BSON formatter to the empty list, effectively making BSON the only response type available. The complete listing can be seen in Listing 2.

Listing 2: Complete Listing of app_start\webapiconfig.cs
using System.Net.Http.Formatting;
using System.Web.Http;

namespace CarInventory21
{
  public static class WebApiConfig
  {
    public static void Register(HttpConfiguration config)
    {
      // Web API configuration and services

      // Web API routes
      config.MapHttpAttributeRoutes();

      config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
      );
            
      config.Formatters.Clear();                             
      // Remove all other formatters
      config.Formatters.Add(new BsonMediaTypeFormatter());   
      // Enable BSON in the web service
    }
  }
}

So far I've built the model and the controller. The only remaining item is a view. For a view, I'll create a simple HTML page. This will serve as a test page and also allow IIS Express to host the ASP.NET Web API. To add a Web page, I right-click on the project and select Add | HTML Page, calling it Index.html.

By default, the links to access this new ASP.NET Web API are:

  • http://localhost:15324/api/car -- to retrieve all car records
  • http://localhost:15324/api/car/car_id -- to retrieve a specific car by ID

Routing is a detailed topic not addressed in this article. However, you can learn more about it here.

[Click on image for larger view.] Figure 10. Adding Index.html to Project

To help facilitate testing, I modify the newly-created page to include all links. The full listing can be found in Listing 3.

Listing 3: Listing of Index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Test Page</title>
</head>
<body>
    <br />    
    To retrieve all car: <a href="/api/car"> /api/car </a> <br />
    <br />
    To retrieve car #1: <a href="/api/car/1"> /api/car/1 </a> <br />
    To retrieve car #2: <a href="/api/car/2"> /api/car/2 </a> <br />
    To retrieve car #3: <a href="/api/car/3"> /api/car/3 </a> <br />
    <br />
</body>
</html>

At this point, the project is ready to run, resulting in the output seen in Figure 11.

[Click on image for larger view.] Figure 11. Result of Index.html When Project Executes

Clicking on the first link to retrieve all cars will download all cars to the browser in BSON format. Currently there's no code to display the retrieved records, so the browser will simply prompt to save the records to a file. Opening the file in Visual Studio will yield the records in Binary format, as seen in Figure 12.

[Click on image for larger view.] Figure 12. Records Retrieved in BSON Format

Reading through the file, you'll see the various hex characters decorating the ASCII characters. These are characteristics of the BSON format. At this stage the ASP.NET Web API is ready to be consumed by clients.

(I'll discuss the various ways an ASP.NET Web API can be consumed by a client process in upcoming articles.)

Lightweight, Flexible Data
ASP.NET Web API 2.1 is currently the latest release from Microsoft. It offers a variety of new features, including the new BSON format. It can be utilized like other formats, but offers a lightweight representation of binary data in a format similar to JSON, which gives Web API 2.1 more flexibility while still remaining simple and easy to configure.

About the Author

Sam Nasr has been a software developer since 1995, focusing mostly on Microsoft technologies. Having achieved multiple certifications from Microsoft (MCAD, MCTS(MOSS), and MCT), Sam develops, teaches, and tours the country to present various topics in .Net Framework. He is also actively involved with the Cleveland C#/VB.Net User Group, where he has been the group leader since 2003. In addition, he also started the Cleveland WPF Users Group in June 2009, and the Cleveland .Net Study Group in August 2009, and is the INETA mentor for Ohio. When not coding, Sam loves spending time with his family and friends or volunteering at his local church. He can be reached by email at [email protected].

comments powered by Disqus

Featured

Subscribe on YouTube