ASP.NET Web API

ASP.NET Web API is a relatively newer technology than Windows Communication Foundation (WCF). It does away with the chatty XML and the entire SOAP envelope. Instead, it uses simple HTTP requests and responses. To get a product with an ID of 5, you can simply issue a GET request for “http://host/products/5”. No HTTP body is required for such a simple GET request. The server will understand the request and reply with the data inside the response body. The response body in ASP.NET Web API is usually JSON.

ASP.NET Web API technology follows the REST standard by default. It provides actions for all CRUD (Create / Read / Update / Delete) operations. We have already seen an example of “Read” above. It uses the GET request and the object is specified by the ID in the URL. Similarly, PUT and POST are used for “Update” and “Create” and DELETE is used for “Delete”. GET, PUT, POST and DELETE are HTTP verbs. You already now GET as it is used in a standard web browser to request a web page. POST is used throughout web in forms to send data. Others are used primarily in REST.

The CRUD operations in ASP.NET Web API are implemented using action methods in controllers – much like what we have already seen in the ASP.NET MVC topic. We will see specific examples shortly.

While ASP.NET Web API might seem to force you into using different HTTP verbs and therefore implement the REST standard, it is not so. If you like, you are free to use HTTP POST requests and responses only. That will take you back to the method like communication you have seen in the Windows Communication Foundation topic.

Please note that while ASP.NET Web API is much more lightweight than WCF, it is not by any chance meant as its replacement. WCF has its place where we need to use a different transport mechanism than HTTP or where it is essential to provide a classic Web Services Description Language (WSDL) to the client. ASP.NET Web API cannot do either of these.

In this section, we will see how to create a simple ASP.NET Web API application. The application will use the default REST standard for CRUD operations and work only with simple .NET types. To test this application, we will create our own client application from scratch. This should give you a basic overview of the ASP.NET Web API technology. Later, we will look at a more sophisticated ASP.NET Web API application with a database connection using complex types. We will also see how to make ASP.NET Web API use the POST verb only.

Simple ASP.NET Web API Application

To create a new ASP.NET Web API Application, start Visual Studio, go to “File” menu and select “New” > “Project”. A new dialog window appears. Select “Web” on the left and then “ASP.NET Web Application”. Now type the name of the application and click “OK”:

New Project 1

In the following window, select that we want to start with an empty application and that we would like to use the “Web API” technology:

New Project 2

Once you click “OK” a new ASP.NET Web API application will be created.

The project does not include any controllers yet. Add a new controller by right-clicking on the “Controllers” folder in the Solution Explorer and selecting “Add” > “Controller…”. In the new window, select the “Web API 2 Controller - Empty” and click “Add”:

Add Controller 1

In the new window, name the new controller as “ProductsController” and click “Add” again:

Add Controller 2

This will create the “ProductsController” class and its own code file. Add this code to the class:

static Dictionary<int, string> products = GetProducts();
 
private static Dictionary<int, string> GetProducts()
{
    Dictionary<int, string> products = new Dictionary<int, string>();
 
    products.Add(1, "Product 1");
    products.Add(2, "Product 2");
    products.Add(3, "Product 3");
    products.Add(4, "Product 4");
 
    return products;
}
 
public List<string> Get()
{
    return products.Select(x => x.Value).ToList();
}
 
public string Get(int id)
{
    return products[id];
}
 
public void Post([FromBody]string value)
{
    products.Add(products.Max(x => x.Key) + 1, value);
}
 
public void Put(int id, [FromBody]string value)
{
    if (products.ContainsKey(id))
        products[id] = value;
    else
        products.Add(id, value);
}
 
public void Delete(int id)
{
    if (products.ContainsKey(id))
        products.Remove(id);
}

Looking at the code, the static “products” data field and the static “GetProducts()” method only make sure we have some data we can play with. The real ASP.NET Web API stuff is below in the Get, Post, Put and Delete methods.

The name of the method always indicates the HTTP verb that is required to invoke it. When using the REST standard, we need to follow this convention to make things simple.

There are two Get methods. Since both are named Get, the GET verb will be required for their invocation. The difference between the two is in the parameter. The parameter-less method returns all our products to the client. The second method returns only the product that matches the “id” specified.

The Post method allows to add a new product. It takes the product name, the “value” parameter, from the request body and creates a new product with a new ID.

The Put method is used when we want to specify not only the product name but its ID as well. This can be used for product creation but more likely it will be used for update operations. When we call this method with a certain ID, providing the product with the ID already exists, it will change its product name.

The Delete method simply deletes a product of the specified ID.

This is basically everything we need to do for our application to work. We can now run it and invoke its Get operation in a web browser for example. The URL will be “http://localhost:port/api/Products” as defined in the “WebApiConfig.cs” file in the “App_Start” folder.

While we can use web browser to issue both GET requests, we will need to create a new client application to test all the other actions.

Keep the server running and create a new simple Console Application. To create a new Console Application, go to “File” menu and select “New” > “Project”. A new dialog window appears. Select “Visual C#” on the left and then “Console Application” on the right. Type the name of the application and click “OK”:

New Project 3

In order to be able to call the Web API server, we will need to use an “HttpClient” class. This class, however, is not part of the .NET Framework itself. We need to get it as a NuGet package. Right-click your project in Solution Explorer, and select “Manage NuGet packages”. In the new window, make sure you are switched to “Online” packages and type “Web API Client” to the search window. Wait a while for the available packages to show up:

Add NuGet Package

Click “Install” on the “Microsoft ASP.NET Web API 2.2 Client Libraries” package and follow its installation. Once it is done, you will get a new assembly reference in your project.

Now, everything is ready to write the invocation code in the Program.cs file. Add this code to the “Main” method in “Program” class:

using (var client = new HttpClient())
{
    client.BaseAddress = new Uri("http://localhost:59699/");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(
        new MediaTypeWithQualityHeaderValue("application/json"));
 
    HttpResponseMessage response = null;
 
    Console.WriteLine("All products:");
    Console.WriteLine("-------------");
 
    response = client.GetAsync("api/Products").Result;
 
    if (response.IsSuccessStatusCode)
    {
        List<string> results =
            response.Content.ReadAsAsync<List<string>>().Result;
 
        foreach (string result in results)
        {
            Console.WriteLine(result);
        }
    }
 
    Console.WriteLine();
    Console.WriteLine("Product with ID = 1:");
    Console.WriteLine("--------------------");
 
    response = client.GetAsync("api/Products/1").Result;
 
    if (response.IsSuccessStatusCode)
    {
        string result = response.Content.ReadAsStringAsync().Result;
        Console.WriteLine(result);
    }
 
    Console.WriteLine();
    Console.WriteLine("Saving new product with ID = 1:");
    Console.WriteLine("-------------------------------");
 
    response = client.PutAsJsonAsync(
        "api/Products/1",
        "New Product 1")
        .Result;
 
    if (response.IsSuccessStatusCode)
    {
        Console.WriteLine("Saved");
    }
 
    Console.WriteLine();
    Console.WriteLine("Product with ID = 1:");
    Console.WriteLine("--------------------");
 
    response = client.GetAsync("api/Products/1").Result;
 
    if (response.IsSuccessStatusCode)
    {
        string result = response.Content.ReadAsStringAsync().Result;
        Console.WriteLine(result);
    }
 
    Console.WriteLine();
    Console.WriteLine("Deleting product with ID = 1:");
    Console.WriteLine("-----------------------------");
 
    response = client.DeleteAsync("api/Products/1").Result;
 
    if (response.IsSuccessStatusCode)
    {
        Console.WriteLine("Deleted");
    }
 
    Console.WriteLine();
    Console.WriteLine("All products:");
    Console.WriteLine("-------------");
 
    response = client.GetAsync("api/Products").Result;
 
    if (response.IsSuccessStatusCode)
    {
        List<string> results =
            response.Content.ReadAsAsync<List<string>>().Result;
 
        foreach (string result in results)
        {
            Console.WriteLine(result);
        }
    }
}
 
Console.ReadLine();

The code listing above is already prepared to be run. It shows how to create a new instance of the “HttpClient” class, how to provide it with a base URL and force it to ask the server for JSON. If we failed to ask for JSON, everything would still work but it would use the chatty XML instead.

You can see that the HttpClient has several asynchronous methods for Get, Put and Delete. It also has a method for Post – it is just not used here in this example. All of these methods are called synchronously using the “.Result” notation. In WinForms or WPF, we would use the “await” keyword instead. You will see this used in the Advanced example in this topic.

The code itself is pretty self-explanatory. Once a request is sent and the response is a success (HTTP 200), it reads the response. If the response is a simple string, ReadAsStringAsync method is used. If the result is a collection, the ReadAsAsync<> method takes care of the collection serialization. The ReadAsAsync<> method is crucial to working with more complex objects as well. You will see this used in the Advanced example in this topic.

You can now run the example – just make sure you change the localhost port to match your server URL. This is what you should get written out to the console:

All products:
-------------
Product 1
Product 2
Product 3
Product 4

Product with ID = 1:
--------------------
"Product 1"

Saving new product with ID = 1:
-------------------------------
Saved

Product with ID = 1:
--------------------
"New Product 1"

Deleting product with ID = 1:
-----------------------------
Deleted

All products:
-------------
Product 2
Product 3
Product 4

The complete Simple ASP.NET Web API Application is available for download.

Advanced ASP.NET Web API Application

Much like the Simple ASP.NET Web API Application, the advanced one shows how to create a separate server and a client. Since the application demonstrates how to return lists of complex types from the database, there is also a common type library used in the examples. Both, the server and the client reference this library.

The server uses POST requests for all operations. This is achieved by the [HttpPost] attribute applied to all action methods. There is also a change of the invocation path made in the WebApiConfig.cs file.

The client application shows how to consume complex types through asynchronous calls. To simplify this, a new helper class has been created.

To learn more about ASP.NET Web API, including error handling as well as everything else already mentioned above, feel free to examine the Advanced Web API Application source code.

This is the last page of this topic.

Go up to: Web Service Applications


Should you have any questions or found a mistake that needs correcting, feel free to send an email to: info [at] mycsharp [dot] net


Advertisements :