Chapter 6. Using AngularJS and ASP.NET Web API for CRUD Operations

This chapter will start with web API routing and then focus on how to create, read, update, and delete records from a database using the ASP.NET Web API, as well as the AngularJS $http and $resource directives. We will also discuss the difference between $http and $resource. At the end of this chapter, we will talk about how to secure the ASP.NET Web API. This chapter covers the following topics:

  • Web API routing:
    • Routing with an action name
    • The ASP.NET Web API attribute routing
  • CRUD operation using $http:
    • Using $http with AngularJS factory
  • CRUD operations using $resource
  • Differentiating between $http and $resource
  • Securing the ASP.NET Web API

Web API routing

Hypertext Transfer Protocol (HTTP) is a client-server computing model, which is used for requests and responses. HTTP is a platform for delivery and collaboration of multi-media, such as audio, video, and hyperlink information systems. It is a basic data communication system for the World Wide Web. Hypertext is an organized text, which uses logical links between the nodes containing text. The client application sends a request to the server. The server, where the application is residing, will return the response containing the sources requested by the client. The response from the server contains the request status information and the content requested by the client. HTTP not only handles the World Wide Web, but it can also be used for web APIs. We can expose a web API using an HTTP protocol. With this protocol, we can serve a broad range of clients, such as web browsers, mobile devices, and Windows applications.

In web APIs, routing is a system for pattern matching, which matches the received request to the web API and it also finds out what to do with the incoming request. Requested URIs will be matched with the controller's action, using the routing engine. The routing engine uses the route table for matching. In the ASP.NET Web API 2, the route is registered automatically in Global.asax under the Application_Start method as shown here:

protected void Application_Start()
{
   GlobalConfiguration.Configure(WebApiConfig.Register);
}

The ASP.NET Web API can be easily integrated with clients using different frameworks and libraries, such as jQuery, AngularJS, and so on.

A controller is a class in the ASP.NET Web API, which handles HTTP requests from clients. The public functions of the controller are known as action functions or only actions. When an ASP.NET Web API receives a request from the client, it routes this request to an action. When we create a web API project using Visual Studio.NET, it will automatically create a WebApiConfig.cs file under the App_Start folder of the project. To decide which action to invoke, the ASP.NET Web API uses the WebApiConfig.cs file. The default WebApiCongif.cs is as shown:

<!-- Attribute Routing -- >

config.MapHttpAttributeRoutes();

<!-- Convention-based routing.-- >

config.Routes.MapHttpRoute(
      name: "DefaultApi",
      routeTemplate: "api/{controller}/{id}",
      defaults: new { id = RouteParameter.Optional }
);

As shown here, the WebApiConfig.cs file contains a routeTemplate: "api/{controller}/{action}/{id}", where the api is a verbatim path section, and {controller} and {id} are variables. If you do not like the api of the default convention of the route template, you can change it. When the ASP.NET Web API receives an HTTP request from the client, it will try to match the URI with one of the action methods of the specified controller. For example, /api/Customers or /api/Customers/1 where Customers is the controller name in the ASP.NET Web API. The controller name will be added to the {controller} variable of the route template. It is to be noted that there is no action variable defined in the default route template of the preceding code. By default, to find the action within the controller, the ASP.NET API framework will map the incoming request to the appropriate action method, depending on HTTP verbs such as, GET, PUT, POST, DELETE, and so on. For example, GetCustomerList. We can enable other HTTP methods by using the ASP.NET Web API attributes on the action method, for instance [HttpPatch].

The following code shows an example of action methods of the Customers controller of the ASP.NET Web API:

public IHttpActionResult GetCustomer()
{
   _db.Configuration.ProxyCreationEnabled = false;

   var customer = _db.Customers;

   if (customer == null)
{
return NotFound();
}
return Ok(customer);
}

        
public IHttpActionResult GetCustomer(string customerID)
{
_db.Configuration.ProxyCreationEnabled = false;

          var customer = _db.Customers.FirstOrDefault(c =>   
           c.CustomerID == customerID);

     if (customer == null)
{
return NotFound();
}
return Ok(customer);
}

        
     public void PutCustomer(Customer data, string customerID)
{

if (data.CustomerID == customerID)
{
_db.Entry(data).State = EntityState.Modified;
      _db.SaveChanges();

    }

}


public void DeleteCustomer(string customerID)
{
Customer customer = _db.Customers.Find(customerID);

     if (customer != null)
{
_db.Customers.Remove(customer);
         _db.SaveChanges();

}
}



public void PostCustomer(Customer customer)
{
_db.Customers.Add(customer);
      _db.SaveChanges();

}

As you can see here, each action method name is prefixed with an HTTP verb. When the appropriate controller is selected in the client request, the ASP.NET Web API framework inspects the HTTP verb of the request and searches for the proper action method to use. If you notice, there are two GET methods in the preceding code: GetCustomer() and GetCustomer(string customerID). It is an example of the overloaded methods used in object-oriented programming (OOP). Method overloading means creating two or more methods with the same name and type, but with a different number or types of parameters. As you can see, GetCustomer() has no parameters, while the GetCustomer(string customerID) requires a customerID parameter. Both methods are of the IHttpActionResult type. If the client sends a request such as, /api/GetCustomer, the ASP.NET Web API invokes the GetCustomer() action. On the other hand, if the client request is api/GetCustomer/3, then the GetCustomer(string customerID) method will be executed.

Routing with an action name

The default routing template within the WebApiConfig file uses the HTTP verb to select the action method. However, you can change the default routing template in order to select the action by the name used in the client request. The following code shows the modified WebApiConfig file:

public static void Register(HttpConfiguration config)
{

<!-- Attribute Routing -- >
    config.MapHttpAttributeRoutes();

    <!-- Convention-based routing.-->
    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{action}/{id}",
        defaults: new { id = RouteParameter.Optional }
);
} 

As you can see in the preceding code in the route template, we added {action}; therefore, the updated route template will be routeTemplate: "api/{controller}/{action}/{id}". In this route template, {action} is a parameter corresponding to the action name in the client request. However, with this type of routing we must use the ASP.NET Web API attribute to specify the HTTP methods. By default, all action methods are GET.

The following code shows an example of action methods using the updated route template:

[HttpGet]
public IHttpActionResult Customer()
{
   _db.Configuration.ProxyCreationEnabled = false;

   var customer = _db.Customers;

   if (customer == null)
{
return NotFound();
}
return Ok(customer);
}

[HttpGet]        
public IHttpActionResult Customer(string customerID)
{
_db.Configuration.ProxyCreationEnabled = false;

          var customer = _db.Customers.FirstOrDefault(c =>   
           c.CustomerID == customerID);

     if (customer == null)
{
return NotFound();
}
return Ok(customer);
}

        
[HttpPut]     
public void Customer(Customer data, string customerID)
{

if (data.CustomerID == customerID)
{
_db.Entry(data).State = EntityState.Modified;
      _db.SaveChanges();

    }

}

  [HttpPost]
  public void Customer(Customer customer)
{
_db.Customers.Add(customer);
      _db.SaveChanges();

}

The client request will be /api/Customer/Customer, where the first Customer is the ASP.NET Web API's controller name and the second Customer is the name of the action method. We've again used the overloaded method. Based on the HTTP verbs, the ASP.NET Web API automatically selects the action method.

The ASP.NET Web API attribute routing

The ASP.NET Web API 2 has new features that are commonly known as direct routing or attribute routing. Attribute routing uses an attribute to define the route of the client request. It gives more control over the URIs in the ASP.NET Web API. For example, we can easily see the URIs with hierarchies of the resources in them. In the preceding WebApiConfig code, the config.MapHttpAttributeRoutes() line supports the attribute routing, along with the traditional routing. Let's consider the scenario where we can use the attribute routing. Let's say we need to find the number of orders in the Northwind database of each employee in each territory. This figure shows the relationship between the Order, Employee, Region, and the Territory tables:

The ASP.NET Web API attribute routing

The preceding figure shows that to get the number of orders handled by a specific employee in a specific region and territory, we need to access the order data within the relationship of the employer and employee relationship with the territory and region. In the traditional way, the URL will be very complicated. However, using the ASP.NET Web API 2 attribute routing, it can be achieved very easily. The client can send the request to the ASP.NET Web API with this URL:

/api/Order/123/AND/Employee/2

In the preceding line of code, we can get the order number 123 handled by the EmployeeID 2. In order to implement the preceding HTTP request, we have to use the ASP.NET Web API attribute route as shown here:

[Route("Agents/{agentId}/{filter}/Territories/{territoryId}")]

In the preceding line of code, we added the {filter} variable to the route.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset