Looking into the ASP.Net Web API - part 1
In this post I would like to show you a hands on example on ASP.Net Web API by building a small ASP.Net application. I am going to build an ASP.Net MVC 4.0 Web application to create a Web API that returns a list of football players. I will also use the popular Javascript library JQuery to issue requests to the server.In the second part of this blog post I will show you how to support more operations in an HTTP service like create,update,delete players using a REST architectural style.
Before I go on with the actual example I will talk a little bit about REST. In 2000, Roy Fielding introduced REpresentational State Transfer in his P.H.D Thesis.
It describes a scalable architecture for building services that build on HTTP.REST is fundamentally different from SOAP.SOAP defines a transport-neutral model that is focused on defining custom services contracts with custom operations.You can invoke those operations over a variety of different transports using different message encodings.REST defines a transport-specific (HTTP) model focused on resources.
In REST we build services around a uniform interface and common data formats.HTTP methods are GET,POST,PUT,DELETE also known as verbs.Data formats supported in REST inculde HTML,XML,JSON.
REST is also known as a Resource Orientated Architecture.The main focus is on identifying and naming resources (URIs). We also focus on how to represent them (XML Format) .We use uniform interface to interact with those URIs through HTTP verbs (GET,POST,PUT,DELETE ). Through this model we can achieve interoperability and scalability for our applications.
Web API is a fully extensible framework for building HTTP based endpoints on top of ASP.Net.It was released with ASP.Net MVC 4.0. It is based on ASP.Net Routing and but is not linked only to ASP.Net MVC. You can use it in a Web Forms project as well. You can download it through NuGet so you can have the latest version.
The most important thing right now is to download and install all the tools,libary,software in your computer so you can follow along. You can download all the necessary software (tools-Visual Studio 2012 Web Edition along with a web server- , a Sql Server instance, libraries,binaries) if you download Web Platform Installer.You can download this tool from this link.
After you install it, you must search for Visual Studio Express 2012 for Web
Have a look at the picture below
Then click Add and then Install.Everything you need will be installed. Maybe you need to reboot the machine so do not worry if you will have to do this.
I have installed Visual Studio 2012 Ultimate edition in my machine which is Windows 8 by the way. I have also installed the latest version of .Net Framework and I will show you later how to download more libraries when needed.I have installed SQL Server 2012 Enterprise Edition in my machine. As a Microsoft Certified Trainer I have access to this software but as explained earlier you need only to download Web Platform Installer and then download the Visual Studio Express 2012 for Web and install it.
Let's start building our ASP.Net MVC 4.0 Web application
1) I am launching VS 2012 and I will Visual C# as the programming language. I will also select ASP.NET MVC 4 Web Application from the available templates.Have a look at the picture below
I have named my application "WebApi" and then clicked OK.
2) From the available templates in the next screen I select Web API. This template will create all the necessary files in order to build the application. Click OK.
Have a look at the picture below.
3) Have a look at the Solution Explorer to get a feeling of the files being created and the structure of the web application. Have a look at the picture below
4) Now we need to add a model that will basically be the data in our application. The way everything works is the following
- We will pass a request to the server, an HTTP request message to the server, then the server will respond with an HTTP response serializing the model to JSON or XML or any other format.
- On the client side serialized data can be parsed and deserialized.Most clients can parse XML and JSON.
Have a look at the picture below to see the how I add a new model to my application. I simply add a class file to my model in the Models folder.
I name the class Footballer.cs
The code follows
public class Footballer
{
public int FootballerID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public double Weight { get; set; }
public double Height { get; set; }
public DateTime JoinedClub { get; set; }
public string PositionPlayed {get;set;}
public int GoalsScored {get;set;}
}
5) We need to add a new controller that basically will handle the HTTP request. Add a new controller, as follows:
In Solution Explorer, right-click the the Controllers folder. Select Add and then select Controller.
Have a look at the picture below
In the Add Controller wizard, name the controller "FootballerController". In the Template drop-down list, select Empty API Controller. Then click Add.
The FootballerController will inherit from the ApiController class and not the Controller class.
I will add the following methods to the class.
public class FootballerController : ApiController
{
Footballer[] footballers = new Footballer[]
{
new Footballer {
FootballerID=1,
FirstName = "Steven",LastName="Gerrard", Height=1.85,
Weight=85, JoinedClub=DateTime.Parse("12/12/1999"),
PositionPlayed="Attacking Midfielder",GoalsScored=23},
new Footballer {
FootballerID=2,
FirstName = "Jamie",LastName="Garragher", Height=1.89,
Weight=89, JoinedClub=DateTime.Parse("12/02/2000"),
PositionPlayed="Central Defender",GoalsScored=2},
new Footballer {
FootballerID=3,
FirstName = "Luis",LastName="Suarez", Height=1.72,
Weight=73, JoinedClub=DateTime.Parse("12/01/2012"),
PositionPlayed="Striker",GoalsScored=27},
};
public IEnumerable<Footballer> GetPlayers()
{
return footballers;
}
public Footballer GetFooballerById(int id)
{
var footballer = footballers.FirstOrDefault((f) => f.FootballerID == id);
if (footballer == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return footballer;
}
}
All my data is stored in an array in memory.We have 2 methods that return data and not view inside the controller class.
GetPlayers() returns a list of players.GetFooballerById(int id) returns a single footballer by its ID.
Each method on the controller will map to a URI.The client (in this case the web browser) will send an HTTP GET request to the URI.
6) Build and run you application. The IIS Express will start, and a notification will appear in the bottom corner of the screen showing the port number that it is running under. A random port number will be selected.
You will see the default page. In my case is http://localhost:57865.Now I must invoke the web API, so must use the following URI http://localhost:57865/api/footballer
Have a look below to see what I see when I view the page in Firefox.It is displayed in XML in the browser.
7) Now we need to test the other two methods. The first one will return a footballer by ID and the second one will return data based on the player's playing position.
While my application is still running I type in the browser http://localhost:57865/api/footballer/1 and hit enter.
Have a look at the picture below to see the results I get in Firefox
While my application is still running I type in the browser http://localhost:57865/api/footballer?position=Attacking%20Midfielder and hit enter.
Have a look at the picture below to see the results I get in Firefox. 8) I will write a small client application , a javascript client in order to consume the APIs.I will modify the Index.cshtml file in the Views folder.I will not be using Razor in this post. I will only use plain HTML 5 and Javascript
The contents of the Index.chstml follow
<!DOCTYPE html>
<html lang="en">
<head>
<title>ASP.NET Web API</title>
<link href="../../Content/Site.css" rel="stylesheet" />
<script src="../../Scripts/jquery-1.7.1.min.js" type="text/javascript">
</script>
<script type="text/javascript">
$(document).ready(function () {
$.getJSON("api/footballer/",
function (data) {
$.each(data, function (key, val) {
var str = val.FirstName + " " + val.LastName;
$('<li/>', { text: str })
.appendTo($('#footballers'));
});
});
});
</script>
</head>
<body id="body" >
<div class="main">
<div>
<h1>All Footballers</h1>
<ul id="footballers"/>
</div>
<div>
<label for="FootballerId">ID:</label>
<input type="text" id="FootballerId" size="5"/>
<input type="button" value="Search" onclick="find();" />
<p id="footballer" />
</div>
</div>
</body>
</html>
Let me explain what I am doing here. There is a link to JQuery library at the top of the script.
I have an HTML 5 markup where I will present the footballers eventually.
With the command below I am sending an Ajax request to the server.The getJSON command does that. The response will be an array of JSON objects. When the request successfully completes, (see code below)
$.each(data, function (key, val) {
var str = val.FirstName + " " + val.LastName;
$('<li/>', { text: str })
.appendTo($('#footballers'));
$.getJSON("api/footballer/",
the data will be returned formatted.
When I build and run the application this is what I get.
My application works. I can see what actually is going on behind the scenes if I have the right tool.
Fiddler is a web debugging proxy tool and you can use it to see all useful information the clients and servers exchange.
You can download Fiddler here.
In my case I am mostly interested in the JSON objects returned from the server.
Have a look at the picture below
9) Now I will show you how to find a footballer by id.
The code for the find() method is
function find() {
var id = $('#FootballerId').val();
$.getJSON("api/footballer/" + id,
function (data) {
var str = data.FirstName + " " + data.LastName;
$('#footballer').text(str);
})
.fail(
function (jqXHR, textStatus, err) {
$('#footballer').text('Error: ' + err);
});
We make a call to the jQuery getJSON function to send the AJAX request.We use the ID to construct the request URI. The response from this request is a JSON representation of a single Footballer object.
Have a look at the picture below
If I enter an invalid ID in the search box, then I get back an HTTP error.
Have a look at the picture below
Now I need to explain how the ASP.NET Web API knows how to map URIs to our controller methods.
The ASP.NET Web API framework for each HTTP message decides which controller receives the request by consulting a route table. The Web API project contains a default route that you can find in the WebApiConfig.cs file.
/api/{controller}/{id}
The {controller} and {id} are just placeholders.
{controller} is matched to the controller name. {controller} in my case is footballer.
The HTTP request method is matched to the method name. (This rule applies only to GET, POST, PUT, and DELETE requests.)
/api/footballer will match the GetPlayers() method
/api/footballer/1 will match the GetFooballerById(1) method
We have a GET request, so the framework looks for a method on FootballerController controller. So there will be a call to the FootballerController controller and for a method whose name starts with "Get...". The FootballerController::GetPlayers() method will execute.
When we pass a parameter (id) to the controller the frameworks call the GetFooballerById, which takes the parameter and returns the footballer object.
The complete code for the Index.cshtml follows
<!DOCTYPE html>
<html lang="en">
<head>
<title>ASP.NET Web API</title>
<link href="../../Content/Site.css" rel="stylesheet" />
<script src="../../Scripts/jquery-1.7.1.min.js" type="text/javascript">
</script>
<script type="text/javascript">
$(document).ready(function () {
$.getJSON("api/footballer/",
function (data) {
$.each(data, function (key, val) {
var str = val.FirstName + " " + val.LastName;
$('<li/>', { text: str })
.appendTo($('#footballers'));
});
});
});
function find() {
var id = $('#FootballerId').val();
$.getJSON("api/footballer/" + id,
function (data) {
var str = data.FirstName + " " + data.LastName;
$('#footballer').text(str);
})
.fail(
function (jqXHR, textStatus, err) {
$('#footballer').text('Error: ' + err);
});
}
</script>
</head>
<body id="body" >
<div class="main">
<div>
<h1>All Footballers</h1>
<ul id="footballers"/>
</div>
<div>
<label for="FootballerId">ID:</label>
<input type="text" id="FootballerId" size="5"/>
<input type="button" value="Search" onclick="find();" />
<p id="footballer" />
</div>
</div>
</body>
</html>
In the second part (next blog post) I will be extending the application to insert,update and delete information.
Hope it helps!!!