Introduction

REST (Representational State Transfer Protocol) is an architectural style to develop distributed applications. It uses HTTP protocol to easily perform CRUD (Create, Retrieve, Update, and Delete) operations on the server.

It is based on a representation of resources. A resource is an object that can be accessed on the World Wide Web (i.e. a record in database). When a user requests a resource from the server, the server returns the representation of that resource. The Web server responds to client calls by retrieving information from the database and returning a result.

In classical WCF service a method like GetAllEmployees() would be exposed to clients. The REST architecture is different from this as it does not work with methods, but with resources or objects (nouns) and it allows verbs (HTTP methods) to operate on them. So, in order to get the Employee record, send an HTTP GET on the object Employee instead of querying a method like GetEmployee().

This post is intended to provide information on how to code one from scratch.

Why use REST?

Develop a Web Service that will be consumed by different operating systems on different platforms. Traditional WCF services in .NET have to be consumed using a proxy, however mobile operating systems such as iOS and Android do not know how to create proxies. Similarly, a proxy cannot be created in Objective C. Objective C only knows how to send basic HTTP verbs GET, POST, PUT and DELETE and expects XML or string as a response. In such scenarios, using REST is the better option.

HTTP Verbs

GET— is one of the basic HTTP verbs. Its main job is to ask the server for a resource. That resource may be an HTML page, a sound file or an image. The GET method is for getting something from the server. The GET method requires sent data to be appended to the URL.

Example: http://someServer.com/api/employee/getAllEmployee

POST— The POST method is used to submit data that needs to be processed to an identified resource. The data is included in the body of the request. This may result in the creation of a new resource, or the updates of existing resources, or both.

Example:

$.ajax({
 async: true,
 url: SomeURL,
 type: "POST",
 contentType: "application/json",
 data: JSON.stringify(someJavaScriptObject),
 success: function(data){},
 error: function(someError){};
 });

PUT – The PUT method is used to submit data that needs to be updated to the identified resource. Like the POST method, the data is included in the body of the request. However, not all of the browsers support this verb.

DELETE – The DELETE method is used to delete a specific resource. Not all of the browsers support this verb.

Controller – In ASP.NET Web API a controller is a collection of HTTP verbs.

Action – Action represents one of the HTTP verbs.

Route – Each action has some route through which it can be accessed using HTTP.

RoutPrefix – This technique is used by ASP.NET Web API 2 to specify a route for a resource.

Http and AcceptVerb() attributes – This is used to specify each method type like GET, POST etc.

WebApiConfig Class – This class is added in each Web API project by ASP.NET. Here we can specify whether to use Web API 1 or Web API 2 techniques for routes identification along with other configurations.

Access-Control-Allow-Origin – Each domain needs permission from the other domain to access its resources. For this purpose we have to mention in our API whether it will allow requests from cross domains or not. This configuration is specified in the Global.asax.cs file.

Below is an example of how to code.

First, create a Web API project, then create a Web Project to consume the Web API. Before creating a Web API, create a simple database in SQL server with a single table (Employee). In this example all CRUD operations will be performed on this table.

Create a Web API Project

  1. Open Visual Studio and select New Project under File menu

ASP-WEB-API (1)

2. Select “NET Web API 2 Empty Project” from project templates as shown in the screenshot below:

ASP-WEB-API (2)

Enter the project name and the location to save it, and then click OK.

3. You will see project structure like the one shown below:

ASP-WEB-API (3)

4. In the Solution Explorer, right-click Controllers to add a controller as shown in the screenshot below:

ASP-WEB-API (4)

Name it EmployeeController as shown below: (Don’t remove the Controller keyword from controller class Name).

ASP-WEB-API (5)

The controller class name must be suffixed with the “Controller” keyword (for example EmployeeController), otherwise ASP.NET will not treat it as a collection of HTTP verbs and will not consider it as a route while serving a request.

5. Add [RoutPrefix(“api/Employee”)] attribute to the EmployeeController class. This will allow the user to access it as http://myWebsite/api/Employee as shown below:

using RestAPI.Models;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace RestAPI.Controllers
{
 [RoutePrefix("api/Employee")]
 public class EmployeeController : ApiController
 {
 }
}

6. Create four methods in EmployeeController like GetAllEmployees(), GetEmployeeByID(string ID), AddEmployee(EmployeeEntity objEmployee), UpdateEmployee(EmployeeEntity objEmployee), DeleteEmployee(string ID). Add attributes [Route(“GetAllEmployees”)], [Route(“GetEmployeeByID/{ID}”)], [Route(“AddEmployee”)], [Route(“UpdateEmployee”)], [Route(“DeleteEmployee”)] to each method and http verbs as [HttpGet], [HttpGet], [HttpPost], [HttpPost], [HttpDelete] to each method respectively.

7. Add logic into each method. One of the methods that has been created by an expert on the matter, is given below for reference:

[Route("GetAllEmployee")]
[HttpGet]
public DataTable GetAllEmployee()
{
 DataSet ds = null;
 try
 {
 using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings[1].ConnectionString))
 {
 cn.Open();
 SqlCommand cmd = new SqlCommand();
 cmd.Connection = cn;
 cmd.CommandType = CommandType.StoredProcedure;
 cmd.CommandText = "SP_SelectAllEmployee";
 SqlDataAdapter da = new SqlDataAdapter(cmd);
 ds = new DataSet();
 da.Fill(ds);
 da.Dispose();
 cmd.Dispose();
 }
 }
 catch (Exception ex)
 {
 throw ex;
 }
 return ds.Tables[0];
}

The [RoutPrefix(“routeprefix”)] technique we have used works in ASP.NET Web API 2 only. This technique is called “Prefix Routing”. To enable this, your WebApiConfig.cs should look like this:

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.MapHttpAttributeRoutes(); this line plays the needed role in ASP.NET Web API 2 Prefix Routing. The lines below were used in the previous version of ASP.Net Web API. ASP.NET Web API 2 has given the user the choice of conventional routing and prefix routing. It is up to the user to decide whether they use conventional or prefix routing.

Access-Control-Allow-Origin

To enable ASP.NET Web API to be used from cross origin (domains other than the one on which REST service is hosted) the following snippet in the Application_BeginRequest method of Global.asax.cs file must be used:

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}

 

Publish this Project

  1. Create a Website in IIS

ASP-WEB-API (6)

2.  Specify a physical path and binding information for this Website, and later the project will be published from visual studio.

ASP-WEB-API (7)

Publish

  1. Go back to Visual Studio, right-click the project in Solution Explorer, and then click Publish

ASP-WEB-API (8)

2. Provide all the required information and click Finish

ASP-WEB-API (9)

Copy this published service URL and then consume it in any client.

Create Website

Create a Website to consume the REST service that we have created and published in IIS.

  1. Open Visual Studio, in the File menu, click New Project.
  2. Select Web, and then click NET Web Application in the template window.
  3. Enter name and specify the location where you want to save the project.
  4. Add a Web Form and name it aspx. This form will be used to display all the employees.

There are two ways to consume a REST service in .NET

  • Through C#
  • Through JSON call

First use the C# method.

Call REST service through C#

  • Open the code behind the file of Employee.aspx page
  • Create a method and include the following lines of code to get all employees from the database
    1. Create an HttpWebRequest object using specified URL
    2. Create an HttpWebResponse object to get the response of the request
    3. Get the response in a stream and convert it to your desired structure like I have converted it to DataTable

Use a similar method to call all the other methods like GetEmployeeByID(), UpdateEmployee() etc.

Code snippet is given below for reference:

public void GetAllEmployee()
{
DataSet ds = new DataSet();
DataTable dt = null;
try
{
string webUrl = "http://localhost:10059/api/Employee/GetAllEmployee";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(webUrl);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
Stream strm = response.GetResponseStream();
StreamReader sReader = null;
if (response.CharacterSet == null)
{
sReader = new StreamReader(strm);
}
else
{
sReader = new StreamReader(strm, Encoding.GetEncoding(response.CharacterSet));
}
dt = (DataTable)JsonConvert.DeserializeObject(sReader.ReadToEnd(), (typeof(DataTable)));
response.Close();
sReader.Close();
}}
catch (Exception ex)
{
throw ex;
}
if (dt != null && dt.Rows.Count > 0)
{
rptrEmployees.DataSource = dt;
rptrEmployees.DataBind();
}}

The call we have sent to REST service is a synchronous call. We can also send asynchronous calls to REST using C# like this:

HttpClient restClient = new HttpClient();
restClient.BaseAddress = new Uri("http://anywebsite.com/");
restClient.DefaultRequestHeaders.Accept.Clear();
restClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await restClient.GetAsync("api/Employee/GetAllEmployees”);
if (response.IsSuccessStatusCode)
{
string resp = await response.Content.ReadAsStringAsync();
}

Call REST through JSON calls

Call REST service using jQuery JSON calls as shown below:

function getAllEmployees() {
 var url = “http://myWebSite.com/api/Employee/GetAllEmployees”;
 $.ajax({
 async: true,
 type: "GET",
 url: url,
 success: function(data){//Your logic here},
 error: function(err){//your logic here}
 });
 }

Summary

This was a basic walkthrough of ASP.NET Web API 2 and all the necessary topics for creating a basic RESTful service have been covered.

References

  1. https://msdn.microsoft.com/en-us/library/dd203052.aspx
  2. http://www.codeproject.com/Articles/112470/Developing-a-REST-Web-Service-using-C-A-walkthroug
  3. http://www.codeproject.com/Articles/21174/Everything-About-REST-Web-Services-What-and-How-Pa
  4. http://www.codeproject.com/Articles/111344/The-Curious-Case-of-Internet-Information-Services
  5. http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/using-web-api-with-aspnet-web-forms
  6. http://www.asp.net/web-api/overview/older-versions/build-restful-apis-with-aspnet-web-api
  7. http://www.codeproject.com/Articles/255684/Create-and-Consume-RESTFul-Service-in-NET-Framewor
  8. http://blogs.msdn.com/b/martinkearn/archive/2015/01/05/introduction-to-rest-and-net-web-api.aspx
  9. http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection