Udostępnij za pośrednictwem


Getting Started on Line-of-Business HTML5 App – Part 11 Serving up JSON Using ASP.NET Web API

imageFor my line of business application to work, I need to get and set data from inside a Web service. I chose JSON to communicate between my Web page and the server. It will be a good choice for your mobile app and Windows 8 app too.

In this post, we’ll combine several technologies to move data from the server to the client.

  • HTML5 to display the data.
  • jQuery AJAX help us load data from the server without a browser page refresh.
  • JSON or JavaScript Object Notation, is a lightweight text-based open standard designed for human-readable data interchange. JSON is often used for serializing and transmitting structured data over a network connection. It is used primarily to transmit data between a server and web application. I chose it as an alternative to XML because it transmits the same data, but in a way that is more terse, requiring less bandwidth.
  • ASP.NET Web API is a framework that makes it easy to build HTTP services that reach a broad range of clients, including browsers and mobile devices. ASP.NET Web API is an ideal platform for building RESTful applications on the .NET Framework.
  • ASP.NET MVC 4 is a framework for building scalable, standards-based web applications using well-established design patterns and the power of ASP.NET and the .NET Framework. We’ll use that to serve up the Web pages.

JSON is perfect for a list of events. I’ll server it up using ASP.NET Web API and consume JSON on  the client using jQuery AJAX.

(Yes. Finally some C#! And I can host my MVC on Windows Azure.)

And to transmit my user’s data. When I deploy, I’ll use SSL to encrypt the data between my user and the application.

JSON List of Events

Here’s my sample JSON for the that my Web page will use to show the Events:

 [
{"EventDate":"\/Date(1352012400000-0700)\/","Id":1,"Location":"Denver","Title":"Event 1"},
{"EventDate":"\/Date(1346742000000-0700)\/","Id":2,"Location":"San Francisco","Title":"Event 2"},
{"EventDate":"\/Date(1349334000000-0700)\/","Id":3,"Location":"Chicago","Title":"Event 3"},
{"EventDate":"\/Date(1352012400000-0700)\/","Id":4,"Location":"London","Title":"Event 4"}
]

The date is a bit ugly, but the rest is straight forward.

{"Id":1,"Location":"Denver","Title":"Event 1"}

and includes the Id, Location, and Title of the events.

As for the EventDate, the JSON Specification doesn’t specify how dates should be represented in a JSON string, so every implementation invented its own way of representing dates. In this case, I'll use the way that Web API sends them.

jQuery AJAX, Web API

I will use jQuery AJAX calls to access my JSON data on a Web Service that is served by Web API.

For example, to get the contact whose ID is 28, the client sends a GET request for https://yourserver/api/contacts/28

I’ll use a jQuery call to get the data. jQuery.getJSON loads JSON-encoded data from the server using a GET HTTP request. The call takes:

  • url. A string containing the URL to which the request is sent.
  • data. A map or string that is sent to the server with the request.
  • success(data, textStatus, jqXHR). A callback function that is executed if the request succeeds.

NOTE: JSON is a data-interchange format with syntax rules that are stricter than those of JavaScript's object literal notation. For example, all strings represented in JSON, whether they are properties or values, must be enclosed in double-quotes.

A Starting Place for Server-Side JSON

HTTP is not just for serving up web pages. It is also a powerful platform for building services. HTTP is simple, flexible, and ubiquitous. Almost any platform that you can think of has an HTTP library, so HTTP services can reach a broad range of clients, including browsers, mobile devices, and traditional desktop applications.

ASP.NET Web API is a framework for building HTTP services on top of the .NET Framework. In Your First ASP.NET Web API (C#) tutorial, you create your first HTTP service using ASP.NET Web API.

Start with creating an MVC4 project using the Web API template. The steps are shown in the tutorial.

Model

Next, add a Model.

A model is an object that represents the data in your application. ASP.NET Web API can automatically serialize your model to JSON, XML, or some other format, and then write the serialized data into the body of the HTTP response message. As long as a client can read the serialization format, it can deserialize the object.

Add a Class to the Model with this code:

 namespace MvcApplication5.Models
{
    public class Event
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Location { get; set; }

        // Web API returns a string that represented the date that looks like this:
        // "\/Date(1291244400000)\/"
        public DateTime EventDate { get; set; }
    }
}

NOTE: The DateTime object will need a bit of work on the client side. Web API will serve up EventDate as a

For more information, see jQuery parseJSON automatic date conversion for Asp.net and ISO date strings and Stand-Alone JSON Serialization on MSDN.

Controller

Next add a Controller.

A controller is an object that handles HTTP requests from the client. When you created your New Project, the wizard created two controllers for you when it created the project. To see them, expand the Controllers folder in Solution Explorer.

You will see HomeController, which is a traditional ASP.NET MVC controller. It is responsible for serving HTML pages for the site, and is not directly related to our Web API service.

Create a new controller named EventController (so named for our events, not for JavaScript nor C# events).

There are two tricks to using this controller. The template inherits from System.Web.Mvc.Controller. Change your controller to inherit from System.Web.Http.ApiController

Add using System.Web.Http; and using MvcApplication5.Models; to the using statements.

 // Default using statements are already included
using System.Web.Http;
using MvcApplication5.Models;

namespace MvcApplication5.Controllers
{
    public class EventsController : ApiController
    {
        // Sample data of events that can be accessed by WebAPI
        private List<Event> events = new List<Event>  
    { 
        new Event() { Id = 1, Title = "Event 1", Location = "Denver", EventDate = new DateTime(2012, 11, 4)}, 
        new Event() { Id = 2, Title = "Event 2", Location = "San Francisco", EventDate = new DateTime(2012, 9, 4)}, 
        new Event() { Id = 3, Title = "Event 3", Location = "Chicago", EventDate = new DateTime(2012, 10, 4) },
        new Event() { Id = 4, Title = "Event 4", Location = "London", EventDate = new DateTime(2012, 11, 4) } 
    };
         // WebAPI will look for 'Get" without a parameter to return all my events
        public IEnumerable<Event> GetAllEvents()
        {
            return events;
        }
         // WebAPI will look for 'Get' with parameter to return a specific event
        // and throw an error if the request is outside the range
         public Event GetEventById(int id)
        {
            if (id < 1 || id > 4)
            {
                throw new System.Web.Http.HttpResponseException(System.Net.HttpStatusCode.NotFound);
            }
            var result =
                from anEvent in events
                where anEvent.Id == id
                select anEvent;

            return result.First();
        }
     }
}

The Linq that creates the result in GetEventById returns the Event whose Id property matches the method’s id parameter.

It also throws an error if id parameter is outside the range of events.

View

Next add a view. The template provides a file named Index.cshtml that renders HTML using the Razor view engine. However, we will not use any Razor features in this tutorial.

In an ASP.NET MVC application, incoming browser requests are mapped to controller actions. We will rely on this feature to return the data into our Web page. In fact, the controller action (in HomeController) will return Index.cshtml as the default Web page that will be our view.

The JavaScript in Index.cshtml (shown in the following sections )will in turn call from the client back into EventController class (shown in the previous section) to display the event data on our Web page.

Let’s start with the skeleton HTML page.

 <!DOCTYPE html> 
<html lang="en"> 
<head> 
    <title>ASP.NET Web API</title> 
    <script src="../../Scripts/jquery-1.6.2.min.js" type="text/javascript"></script> 

</head> 
<body> 
    <div> 
        <h1>All Events</h1> 
        <ul id='events' /> 
    </div> 
    <div> 
        <label for="eventId">ID:</label> 
        <input type="text" id="eventId" size="5"/> 
        <input type="button" value="Search" onclick="find();" /> 
        <p id="event" /> 
    </div> 
</body> 
</html>

Next, we’ll insert JavaScript to get the data from the EventController.

The getJSON function sends the jQuery AJAX request.

The first parameter is send an HTTP GET request to "/api/events" , which Web API maps to the EventController class. The response will be an array of JSON objects.

WebAPI uses the convention of putting api into the pathname.

The second parameter to getJSON is a callback function that is invoked when the request successfully completes.

     <script type="text/javascript">
    $(document).ready(function () {
        // Send an AJAX request
        $.getJSON ("api/events/",
            function (data) {
                // On success, 'data' contains a list of events.
                $.each(data, function (key, val) {
                    // Format the text to display.
                    var str = val.Title + ': ' + val.Location;

                    // Add a list item for the product.
                    $('<li/>', { html: str }).appendTo($('#events'));
                });
            });
    });

    function find() {
        var id = $('#eventId').val();
        $.getJSON("api/events/" + id,
                function (data) {
                    var str = data.Title + ': ' + data.Location;
                    $('#event').html(str);
                })
            .fail(
                function (jqXHR, textStatus, err) {
                    $('#event).html('Error: ' + err);
                });
    }
    </script> 

The find function retrieves the JSON for a specific event using a parameter such as,  api/events/3, where the 3 is the id of the row. Web API uses the ID to call the EventsController.GetEventById(int id) method that returns a Model.Event object.

Also, the fail function of getJSON returns an error and inserts it into the paragraph whose id is event.

As for That Nasty Date

I need to transform the date into something that users can read.

I parse the EventDate and extract the number. I take that under and turn it into an integer. That integer is used to create a new instance of Date.

To show the date, replace the JSON call that retrieves the data with the code to form the month, day, and year using the following code:

 // Send an AJAX request
$.getJSON ("api/events/",
 function (data) {
        // On success, 'data' contains a list of events.
        $.each(data, function (key, val) {
        
         // Need to transform the date returned by WebAPI in val.EventDAte into
        // from a date that looks like this 
        // '/Date(1224043200000)/'
        // into a date that can be used in my UI.
        // for the purposes of this code, all date times are local
        var d = new Date(parseInt(val.EventDate.slice(6, -2)));
        var displaydate = ('' + (1 + d.getMonth()) + '/' + d.getDate() + '/' + d.getFullYear().toString().slice(-2));

        // Format the text to display.
        var str = val.Title + ': ' + val.Location + ' on ' + displaydate;

        // Add a list item for the product.
        $('<li/>', { html: str }).appendTo($('#events'));
    });
});

Or maybe I should have just used string and kept the DateTime inside the Model.Event class.

In any case, here’s the result:

image

More About Web API

Web APIs can be accessed from a broad range of clients (ranging from browsers using JavaScript, to native apps on any mobile/client platform). It provides the following support:

  • Modern HTTP programming model: Directly access and manipulate HTTP requests and responses in your Web APIs using a clean, strongly typed HTTP object model.
  • Content negotiation: Web API has built-in support for content negotiation – which enables the client and server to work together to determine the right format for data being returned from an API.
  • Query composition: Web API enables you to easily support querying via the OData URL conventions.
  • Model binding and validation: Model binders provide an easy way to extract data from various parts of an HTTP request and convert those message parts into .NET objects which can be used by Web API actions.
  • Routes: Web APIs support the full set of routing capabilities supported within ASP.NET MVC and ASP.NET today, including route parameters and constraints. Web API also provides smart conventions by default, enabling you to easily create classes that implement Web APIs without having to apply attributes to your classes or methods. Web API configuration is accomplished solely through code – leaving your config files clean.
  • Filters: Web APIs enables you to easily use and create filters (for example: [authorization]) that enable you to encapsulate and apply cross-cutting behavior.
  • Improved testability: Rather than setting HTTP details in static context objects, Web API actions can now work with instances of HttpRequestMessage and HttpResponseMessage – two new HTTP objects that (among other things) make testing much easier.
  • IoC Support: Web API supports the service locator pattern implemented by ASP.NET MVC, which enables you to resolve dependencies for many different facilities. You can easily integrate this with an IoC container or dependency injection framework to enable clean resolution of dependencies.
  • Flexible Hosting: Web APIs can be hosted within any type of ASP.NET application.

For more information, see Web API.

CRUD Operations Using Web API

For information about how to build your Web API classes for complete CRUD operations, see Creating a Web API that Supports CRUD Operations. This provides a good template for how you can perform the four basic database operations of CRUD("Create, Read, Update, and Delete") . Many HTTP services also model CRUD operations through REST or REST-like APIs.

For More Information

jQuery AJAX
JSON or JavaScript Object Notation
ASP.NET Web API
ASP.NET MVC
Node.js

Reference Application

projectsilk Project Silk provides guidance for building cross-browser web applications with a focus on client-side interactivity. These applications take advantage of the latest web standards like HTML5, CSS3 and ECMAScript 5 along with modern web technologies such as jQuery, Internet Explorer 9, and ASP.NET MVC3.

To illustrate this guidance, the project includes a reference implementation called Mileage Stats that enables its users to track various metrics about their vehicles and fill-ups. Much of the effort in building Mileage Stats was applied to the usability and interactivity of the experience. Animations were included to enhance the enjoyment of the site and AJAX is used to keep the interface responsive and immersive. A great deal of care was also taken to ensure the client-side JavaScript facilitates modularity and maintainability. To accomplish these design goals, the JavaScript code was structured into “widgets” that benefit from the jQuery UI Widget Factory.

 

Bruce D. KyleISV Developer Evangelist | Microsoft Corporation

image