Working with ASP.NET Web API

Exclusive offer: get 50% off this eBook here
ASP.NET Web API: Build RESTful web applications and services on the .NET framework

ASP.NET Web API: Build RESTful web applications and services on the .NET framework — Save 50%

Master ASP.NET Web API using .NET Framework 4.5 and Visual Studio 2013 with this book and ebook

$29.99    $15.00
by Joydip Kanjilal | December 2013 | .NET Web Development

In this article by Joydip Kanjilal, the author of ASP.NET Web API, you will learn about working with ASP.NET Web API.

(For more resources related to this topic, see here.)

The ASP.NET Web API is a framework that you can make use of to build web services that use HTTP as the protocol. You can use the ASP.NET Web API to return data based on the data requested by the client, that is, you can return JSON or XML as the format of the data.

Layers of an application

The ASP.NET Framework runs on top of the managed environment of the .NET Framework.

The Model, View, and Controller (MVC) architectural pattern is used to separate the concerns of an application to facilitate testing, ease the process of maintenance of the application's code, and to provide better support for change. The model represents the application's data and the business objects; the view is the presentation layer component, and the controller binds the model and the view together. The following figure illustrates the components of Model View Architecture:

The MVC Architecture

The ASP.NET Web API architecture

The ASP.NET Web API is a lightweight web-based architecture that uses HTTP as the application protocol. Routing in the ASP.NET Web API works a bit differently compared to the way it works in ASP.NET MVC. The basic difference between routing in MVC and routing in a Web API is that, Web API uses the HTTP method, and not the URI path, to select the action. The Web API Framework uses a routing table to determine which action is to be invoked for a particular request. You need to specify the routing parameters in the WebApiConfig.cs file that resides in the App_Start directory.

Here's an example that shows how routing is configured:

routes.MapHttpRoute(    name: "Packt API Default",     routeTemplate: "api/{controller}/{id}",     defaults: new { id = RouteParameter.Optional } );

The following code snippet illustrates how routing is configured by action names:

routes.MapHttpRoute(     name: "PacktActionApi",     routeTemplate: "api/{controller}/{action}/{id}",     defaults: new { id = RouteParameter.Optional } );

The ASP.NET Web API generates structured data such as JSON and XML as responses. It can route the incoming requests to the actions based on HTTP verbs and not only action names. Also, the ASP.NET Web API can be hosted outside of the ASP.NET runtime environment and the IIS Web Server context.

Routing in ASP.NET Web API

Routing in the ASP.NET Web API is very much the same as in the ASP.NET MVC. The ASP.NET Web API routes URLs to a controller. Then, the control is handed over to the action that corresponds to the HTTP verb of the request message. Note that the default route template for an ASP.NET Web API project is {controller}/{id}—here the {id} parameter is optional. Also, the ASP.NET Web API route templates may optionally include an {action} parameter. It should be noted that unlike the ASP.NET MVC, URLs in the ASP.NET Web API cannot contain complex types. It should also be noted that complex types must be present in the HTTP message body, and that there can be one, and only one, complex type in the HTTP message body.

Note that the ASP.NET MVC and the ASP.NET Web API are two distinctly separate frameworks which adhere to some common architectural patterns.

In the ASP.NET Web API framework, the controller handles all HTTP requests. The controller comprises a collection of action methods—an incoming request to the Web API framework, the request is routed to the appropriate action. Now, the framework uses a routing table to determine the action method to be invoked when a request is received.

Here is an example:

routes.MapHttpRoute(     name: "Packt Web API",     routeTemplate: "api/{controller}/{id}",     defaults: new { id = RouteParameter.Optional } );

Refer to the following UserController class.

public class UserController <UserAuthentication>: BaseApiController<UserAuthentication> {     public void GetAllUsers() { }     public IEnumerable<User> GetUserById(int id) { }     public HttpResponseMessage DeleteUser(int id){ } }

The following table illustrates the HTTP method and the corresponding URI, Actions, and so on:

HTTP Method

URI

Action

Parameter

GET

api/users

GetAllUsers

None

GET

api/users/1

GetUserByID

1

POST

api/users

 

 

DELETE

api/users/3

DeleteUser

3

The Web API Framework matches the segments in the URI path to the template. The following steps are performed:

  1. The URI is matched to a route template.
  2. The respective controller is selected.
  3. The respective action is selected.

The IHttpControllerSelector.SelectController method selects the controller, takes an HttpRequestMessage instance and returns an HttpControllerDescriptor. After the controller has been selected, the Web API framework selects the action by invoking the IHttpActionSelector.SelectAction method. This method in turn accepts HttpControllerContext and returns HttpActionDescriptor. You can also explicitly specify the HTTP method for an action by decorating the action method using the HttpGet, HttpPut, HttpPost, or HttpDelete attributes. Here is an example:

public class UsersController : ApiController {     [HttpGet]     public User FindUser(id) {} }

You can also use the AcceptVerbs attribute to enable HTTP methods other than GET, PUT, POST, and DELETE. Here is an example:

public class UsersController : ApiController {     [AcceptVerbs("GET", "HEAD")]     public User FindUser(id) { } }

You can also define route by an action name. Here is an example:

routes.MapHttpRoute(     name: "PacktActionApi",     routeTemplate: "api/{controller}/{action}/{id}",     defaults: new { id = RouteParameter.Optional } );

You can also override the action name by using the ActionName attribute. The following code snippet illustrates two actions: one that supports GET and the other that supports POST:

public class UsersController : ApiController {     [HttpGet]     [ActionName("Token")]     public HttpResponseMessage GetToken(int userId);     [HttpPost]     [ActionName("Token")]     public void AddNewToken(int userId); }

 

ASP.NET Web API: Build RESTful web applications and services on the .NET framework Master ASP.NET Web API using .NET Framework 4.5 and Visual Studio 2013 with this book and ebook
Published: December 2013
eBook Price: $29.99
Book Price: $49.99
See more
Select your format and quantity:

Implementing ASP.NET Web API for the Security database

To implement the ASP.NET Web API, you need to create a class that derives from the ApiController class. Now, the methods defined in the Web API controller map to the corresponding HTTP methods. You should ensure that the actions you would like to implement in your Web API Controller class should be prefixed with the correct request type (GET, POST, PUT, and DELETE).

To create an ASP.NET Web API for our Security database, follow these steps:

  1. Right-click on the solution explorer window.
  2. Select Add New Project.
  3. Creating a new ASP.NET Web API Project

  4. Select ASP.NET MVC 4 Web Application from the list of the templates under the Web category as shown in the previous figure.
  5. Specify a name for the project and click on OK.
  6. Select Web API as the Project Template as shown in the following screenshot:
  7. Selecting the project template

  8. Ensure that View engine selected is Razor. Click on OK when done.

Here is how the HomeController class looks:

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace ASP.NET.MVC.WebAPI.Controller {     public class HomeController : Controller     {         public ActionResult Index()         {             return View();         }     } }

Here is how the ValuesController class looks:

using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; namespace ASP.NET.MVC.WebAPI.Controllers {     public class ValuesController : ApiController     {         // GET api/values         public IEnumerable<string> Get()         {             return new string[] { "value1", "value2" };         }         // GET api/values/5         public string Get(int id)         {             return "value";         }         // POST api/values         public void Post([FromBody]string value)         {         }         // PUT api/values/5         public void Put(int id, [FromBody]string value)         {         }         // DELETE api/values/5         public void Delete(int id)         {         }     } }

Now when you execute the application; here is how the output looks:

The output in the web browser

Let's create an entity class called Employee and use it in the ValuesController class. I've kept the Employee class as simple as possible:

public class Employee     {         public Int32 ID { get; set; }         public String FirstName { get; set; }         public String LastName { get; set; }     }

We will now create an array of the Employee class and store some data in it using the constructor. Note that an ASP.NET Web API controller derives from ApiController. Here is how the updated ValuesController class looks:

public class ValuesController : ApiController     {         Employee[] employeeArray = null;         public ValuesController()         {             employeeArray = new Employee[]{                new Employee {ID = 1, FirstName = "Joydip",                  LastName = "Kanjilal"},                new Employee {ID = 2, FirstName = "Steve", LastName                  = "Smith"},                new Employee {ID = 3, FirstName = "Michael",                  LastName = "Stevens"}                           };         }         public IEnumerable<Employee> Get()         {             return employeeArray;         }         public string GetFullName(int id)         {             return employeeArray[id].FirstName + " " +               employeeArray[id].LastName;         }     }

Let us now see how the output looks when we execute the application and invoke the Web API.

The ValuesController class in execution

Now, let's invoke the Web API controller and pass the Employee ID as parameter. Here is how the output looks like:

Retrieving a particular record

ASP.NET Web API: Build RESTful web applications and services on the .NET framework Master ASP.NET Web API using .NET Framework 4.5 and Visual Studio 2013 with this book and ebook
Published: December 2013
eBook Price: $29.99
Book Price: $49.99
See more
Select your format and quantity:

We will now design a BaseApiController class—a class that would serve as base for all controller classes. Here is how the initial version of this class would look:

public class BaseApiController<T> : ApiController where T : class {     BaseRepository<SecurityEntities> repository = null;     public BaseApiController()     {         repository = new          BaseRepository<SecurityEntities>          ("SecurityEntities");     } }

Here is how the initial version of the BaseRepository class looks:

public class BaseRepository<TContext> : IDisposable   where TContext : DbContext, IObjectContextAdapter, new() {     private TContext context;     private BaseRepository()     {     }     public BaseRepository(string connectionStringName)     {         context = new TContext();       context.Database.Connection.ConnectionString =           "data source=Joydip;initial catalog=SecurityDB;           integrated security=True;";    } }

Here's the complete implementation of the BaseRepository class:

using System; using System.Linq; using System.Data.Entity; using System.Linq.Expressions; using System.Reflection; using System.Data.Entity.Infrastructure; using System.Data; namespace DataAccess {     public class BaseRepository<TContext> : IDisposable       where TContext : DbContext, IObjectContextAdapter, new()     {         private TContext dataContext;         private BaseRepository()         {         }         public BaseRepository(string connectionStringName)         {             dataContext = new TContext();             dataContext.Database.Connection.ConnectionString =               "datasource=Joydip;initial catalog=SecurityDB;               integrated security=True;";         }                  public virtual Int32 CreateData<T>(T TObject) where T :           class         {             var dbSetInstance = dataContext.Set<T>().Add(TObject);             return SaveChanges();         }         public virtual Int32 RemoveData<T>(T instance) where T :           class         {             dataContext.Set<T>().Remove(instance);             return SaveChanges();         }         public virtual Int32 EditData<T>(T instance) where T :           class         {             var dbEntityEntry = dataContext.Entry(instance);             dataContext.Set<T>().Attach(instance);             dbEntityEntry.State = EntityState.Modified;             return SaveChanges();         }         private Int32 SaveChanges()         {             return dataContext.SaveChanges();         }         public void Dispose()         {             if (dataContext != null)             {                 dataContext.Dispose();                 dataContext = null;             }         }     } }

Here is how the IBaseApiController interface looks:

using System; namespace ASP.NET.MVC.WebAPI.Models {     /// <summary>     /// IBaseApiController interface     /// </summary>     public interface IBaseApiController : IDisposable     {         int ID { get; set; }            } }

The BaseApiController class extends the ApiController class and implements the IBaseApiController interface:

using System; using System.Collections.Generic; using System.Web.Http; using ASP.NET.MVC.WebAPI.Models; using DataAccess; namespace ASP.NET.MVC.WebAPI.Helpers {     public class BaseApiController<T>: ApiController where T :       class, IBaseApiController     {       BaseRepository<SecurityEntities> repository = null;         protected string[] includesArray { get; set; }         /// <summary>         /// Default Contructor that initializes the instance of           BaseRepository         /// </summary>         public BaseApiController()         {             repository = new BaseRepository              <SecurityEntities>("SecurityEntities");         }        /// <summary>         /// Get method to retrieve entity data based on the           generic type supplied         /// </summary>         /// <returns></returns>         public virtual IEnumerable<T> Get()         {             return repository.GetData<T>(includesArray);         }         /// <summary>         /// Get method to retrieve entity data based on the id of           the entity         /// </summary>         /// <param name="id"></param>         /// <returns></returns>         public virtual T Get(Int32 id)         {             return repository.SearchData<T>(t => t.ID == id,               includesArray);         }         /// <summary>         /// Post method - edits data         /// </summary>         /// <param name="value"></param>         /// <returns></returns>         public virtual Int32 Post([FromBody]T value)         {             return repository.EditData<T>(value);         }         /// <summary>         /// Put method - creates / inserts new entity         /// </summary>         /// <param name="value"></param>         /// <returns></returns>         public virtual Int32 Put([FromBody]T value)         {             return repository.CreateData<T>(value);         }         /// <summary>         /// Delete method - deletes an existing entity         /// </summary>         /// <param name="value"></param>         /// <returns></returns>         public virtual Int32 Delete([FromBody]T value)         {             return repository.RemoveData<T>(value);         }     } }

In a standard ASP.NET MVC project, the route configuration is defined in the Global.asx.cs file. On the contrary, in a standard ASP.NET Web API project you would have a RouteConfig class and a WebApiConfig class inside the Application_Start folder.

RouteConfig and WebApiConfig in ASP.NET Web API

Note that the RouteConfig.cs file is similar to a standard ASP.NET MVC project and is used to set up routes for the MVC framework. The WebApiConfig.cs file is actually where the ASP.NET Web API routing configuration is specified. The WebApiConfig class looks like this:

using System; using System.Collections.Generic; using System.Linq; using System.Web.Http; namespace ASP.NET.MVC.WebAPI {     public static class WebApiConfig     {         public static void Register(HttpConfiguration config)         {             config.Routes.MapHttpRoute(                 name: "DefaultApi",                 routeTemplate: "api/{controller}/{id}",                 defaults: new { id = RouteParameter.Optional }             );         }     } }

Here are the links to further references on this topic:

Summary

In this article, we explored the ASP.NET Web API with special focus on how routing and security is handled in the ASP.NET Web API.

Resources for Article:


Further resources on this subject:


About the Author :


Joydip Kanjilal

Joydip Kanjilal is a Microsoft Most Valuable Professional in ASP.NET, a speaker, and the author of several books and articles. He has over 16 years of experience in the IT industry, with more than 10 years using Microsoft .NET and its related technologies. He was selected as the MSDN Featured Developer of the Fortnight a number of times and also as the Community Credit Winner by www.communitycredit. com several times. He has authored the following books:

  • Visual Studio Six in One (Wrox Publishers)
  • ASP.NET 4.0 Programming (Mc-Graw Hill Publishing)
  • Entity Framework Tutorial (Packt Publishing)
  • Pro Sync Framework (APRESS)
  • Sams Teach Yourself ASP.NET Ajax in 24 Hours (Sams Publishing)
  • ASP.NET Data Presentation Controls Essentials (Packt Publishing)

He has also authored more than 250 articles for some of the most reputable sites, such as www.msdn.microsoft.com, www.code-magazine.com, www.asptoday.com, www.devx.com, www.ddj.com, www.aspalliance.com, www.aspnetpro.com, www.sql-server-performance.com, and www.sswug.com. A lot of these articles have been selected at www.asp.net—Microsoft's official website on ASP.NET.

He has years of experience in designing and architecting solutions for various domains. His technical strengths include C, C++, VC++, Java, C#, Microsoft .NET, Ajax, WCF, REST, SOA, Design Patterns, SQL Server, Operating Systems, and Computer Architecture.

For more details, please refer to the following links:

Books From Packt


Building Mobile Applications Using Kendo UI Mobile and ASP.NET Web API
Building Mobile Applications Using Kendo UI Mobile and ASP.NET Web API

Microsoft AJAX Library Essentials: Client-side ASP.NET AJAX 1.0 Explained
Microsoft AJAX Library Essentials: Client-side ASP.NET AJAX 1.0 Explained

ASP.NET 3.5 Application Architecture and Design
ASP.NET 3.5 Application Architecture and Design

ASP.NET jQuery Cookbook
ASP.NET jQuery Cookbook

ASP.NET MVC 2 Cookbook
ASP.NET MVC 2 Cookbook

ASP.NET 3.5 CMS Development
ASP.NET 3.5 CMS Development

ASP.NET 3.5 CMS Development
ASP.NET 3.5 CMS Development

ASP.NET 4 Social Networking
ASP.NET 4 Social Networking


No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
f
g
6
5
p
i
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software