Quantcast
Channel: ASP.Net Web API – Bit of Technology
Viewing all articles
Browse latest Browse all 37

What is New in ASP.Net Web API 2 – Part 1

$
0
0

Asp.Net Web API 2 has been released with the release of Asp.Net MVC 5 since 5 months ago, Web API 2 can be used with .NET framework 4.5 only, the Web API 2 template is available by default on VS 2013 and you can install Web Tools 2013.1 for VS 2012 to have this template as well by visiting this link.

In my previous tutorial on Building ASP.Net Web API RESTful service, I’ve covered different features of the first release of ASP.Net Web API, in this two series post (part 2 can be found here) I will focus on the main features in version 2, I’ll be using the same project I’ve used in the previous tutorial but I will start new Web API 2 project then we’ll implement and discuss the new features. The source code for the new Web API 2 project can be found on my GitHub repository.

Note: I will not upgrade the existing eLearning Web API to version 2, but if you are interested to know how to upgrade version 1 to version 2 then you can follow the steps in ASP.Net official post here.

What is new in ASP.Net Web API 2?

ASP.Net Web API 2 comes with a couple of nice features and enhancements, the most four important features in my opinion are:

  1. ASP.Net Web API 2 Attribute Routing:

    • Web API 2 now supports attribute routing along with the conventional based routing where we used to define a route per controller inside “WebApiConfig.cs” class. Using attribute routing is very useful in situation that we have a single controller which is responsible for multiple actions, with version 2 the routes now can be defined directly on the controller or at the action level.
  2. IHttpActionResult:

    • In the first version of Asp.Net Web API we always returned HTTP response messages for all HTTP verbs using the extension method Request.CreateResponse and this was really easy, now with version 2 of ASP.Net Web API this is simplified more by introducing a new interface named IHttpActionResult, this interface acts like a factory for HttpResponseMessage with a support for custom responses such as (Ok, BadRequest,Notfound, Unauthorized, etc…).
  3. Cross Origin Resource Sharing Support (CORS):

    • Usually webpages from different domain are not allowed to issue AJAX requests to HTTP Services (API) on other domains due to Same-Origin Policy, the solution for this was to enable JSONP response. But in ASP.Net Web API 2 enabling CORS support is made easy, once you enable CORS it will allow JavaScript on webpage to send AJAX requests to another HTTP Service (API) on a different domain. This can be configured on the entire API, on certain controller, or even on selected actions.
  4. Enhancement on oData Support.

    • Note: I’ll not cover this in the current post as I’m planing to do dedicated series of posts on oData support for ASP.Net Web API.

Let’s cover the new features in practical example

As stated before and to keep things simple we’ll depend on my previous tutorial eLearning API concepts to demonstrate those features. All we want to use from the eLearning API is its data access layer and database model, as well the same repository pattern, in other words w’ll use only project eLearning.Data, if you are interested to know how we built the eLearning.Data project then you can follow along on how we created the database model here and how we applied the repository pattern here.

Once you have your database access layer project ready then you can follow along with me to create new eLearning.WebAPI2 project to demonstrate those new features.

I will assume that you have Web Tools 2013.1 for VS 2012 installed on your machine, so you can use the ASP.NetWeb API 2 template directly which will add the needed assemblies for ASP.Net Web API2.

Step 1: Create new empty ASP.Net Web API 2 project

We’ll start by creating a new empty ASP.Net Web API 2 project as the image below, you can name your project “eLearning.WebAPI2”, do not forget to choose .NET framework 4.5 version. Once The project is added we need install Entity Framework version 6 using NuGet package manager or NuGet package console, the package we’ll install is named “EntityFramework“. When the package is installed, we need to  add a reference for the class library “eLearning.Data” which will act as our database repository.

Web API 2 Project Template

 

 

 

 

Step 2: Configuring routes

The ASP.Net Web API 2 template we used has by default a class named “WebApiConfig” inside the “App_Start” folder, when you open this class you will notice that there is new line 

config.MapHttpAttributeRoutes();
 this didn’t exists in Web API version one, the main responsbility for this line of code is to enable Attribute Routing feature in Web API version 2 where we can define routes on the controller directly. In this tutorial we want to use routing by attributes only to route all requests, so feel free to delete the default route named “DefaultApi”.

The other important change introduced in Web API 2 is how the “WebApiConfig” file is registered, go ahead and open class “Global.asax”  and you will notice that there is new line used for configuring the routes 

GlobalConfiguration.Configure(WebApiConfig.Register);
 this line is responsible for registering the routes when the global configuration class is initiated and ready to be called.

Step 3: Adding first controller (Courses Controller)

Now we want to add a Web API Controller which will handle HTTP requests issues against the URI “/api/courses”. To do this right-click on Controllers folder->Select Add->Name the controller “CoursesController” and choose “Empty API Controller” Template. Note: It is not required to name the controller “CoursesController” as we used in Web API version 1, now the controllers selection are based on the attributes we define not the routes which used be configured in class “WebApiConfig”

We’ll add support for getting single course by id and getting all courses. There are different ways to define routing attributes, you can define route prefix on controller level, and you can define them on action level. As well we’ll cover how we can configure routing to an exceptional route within the same controller. Below are the scenarios we’ll cover:

1. Define attributes on action level

Let’s Implement the code below which add support for handling and HTTP GET request sent to the URI “api/courses/23″:

public class CoursesController : ApiController
    {
        [Route("api/courses/{id:int}")]
        public HttpResponseMessage GetCourse(int id)
        {
            Learning.Data.LearningContext ctx = null;
            Learning.Data.ILearningRepository repo = null;

            try
            {
                ctx = new Learning.Data.LearningContext();
                repo = new Learning.Data.LearningRepository(ctx);

                var course = repo.GetCourse(id, false);
                if (course != null)
                {
                    return Request.CreateResponse(HttpStatusCode.OK, course);
                }
                else
                {
                    return Request.CreateResponse(HttpStatusCode.NotFound);
                }

            }
            catch (Exception ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
            }
            finally
            {
                ctx.Dispose();
            }
        }
}

What we have done here is simple, if you look at the highlighted line of code above you will notice how we defined the route on action level by using attribute 

System.Web.Http.Route
 where we specified the request URI and stated that id parameter should be integer, if you tried to issue GET request to URI “/api/courses/abc” you will get 404 response.

In Web API version 1 we used to define names for routes inside “WebApiConfig” class, those names were useful as we used them to link each resource to URI or for results navigation purpose, in our case we still need to return “PrevPageLink” and “NextPageLink” in the response body when user issue HTTP GET request to URI “/api/courses”. This still available in Web API version 2 but defining route names will take place on the attribute level, let’s implement the code below:

public class CoursesController : ApiController
    {
	[Route("api/courses/", Name = "CoursesRoute")]
        public HttpResponseMessage Get(int page = 0, int pageSize = 10)
        {
            IQueryable<Course> query;

            Learning.Data.LearningContext ctx = new Learning.Data.LearningContext();

            Learning.Data.ILearningRepository repo = new Learning.Data.LearningRepository(ctx);

            query = repo.GetAllCourses().OrderBy(c => c.CourseSubject.Id);
            var totalCount = query.Count();
            var totalPages = (int)Math.Ceiling((double)totalCount / pageSize);

            var urlHelper = new UrlHelper(Request);
            var prevLink = page > 0 ? urlHelper.Link("CoursesRoute", new { page = page - 1, pageSize = pageSize }) : "";
            var nextLink = page < totalPages - 1 ? urlHelper.Link("CoursesRoute", new { page = page + 1, pageSize = pageSize }) : "";

            var results = query
                          .Skip(pageSize * page)
                          .Take(pageSize)
                          .ToList();

            var result = new
            {
                TotalCount = totalCount,
                TotalPages = totalPages,
                PrevPageLink = prevLink,
                NextPageLink = nextLink,
                Results = results
            };

            return Request.CreateResponse(HttpStatusCode.OK, result);

        }
   }

In the code above notice how we defined the route name on attribute level, you can not define route names on Controller level so if you have another actions need route names then you have to define them on each attribute.

2. Define attributes on controller level

Now instead of repeating the prefix “/api/courses” on each action, we can add this prefix on controller level and define the specific route attributes information on each action, the change is fairly simple as the code below:

[RoutePrefix("api/courses")]
public class CoursesController : ApiController
	{
		[Route(Name = "CoursesRoute")]
		public HttpResponseMessage Get(int page = 0, int pageSize = 10)
		{
			/*Rest of implementation goes here*/
		}

		[Route("{id:int}")]
		public HttpResponseMessage GetCourse(int id)
		{
			/*Rest of implementation goes here*/
		}
	}

3. Routing to exceptional route

In some cases you need to route to different URI while you are on the same controller, this was not possible in Web API version 1 but it’s very easy to implement in version 2, assume that we want to get all courses names based on certain subject, our URI have to be on the form: “api/subjects/{subjectid}/courses” lets implement this by adding the code below:

[Route("~/api/subject/{subjectid:int}/courses")]
public HttpResponseMessage GetCoursesBySubject(int subjectid)
{
	Learning.Data.LearningContext ctx = null;
	Learning.Data.ILearningRepository repo = null;
	IQueryable<Course> query;

	try
	{
		ctx = new Learning.Data.LearningContext();
		repo = new Learning.Data.LearningRepository(ctx);

		query = repo.GetCoursesBySubject(subjectid);
		var coursesList = query.Select(c => c.Name).ToList();
		if (coursesList != null)
		{
			return Request.CreateResponse(HttpStatusCode.OK, coursesList);
		}
		else
		{
			return Request.CreateResponse(HttpStatusCode.NotFound);
		}

	}
	catch (Exception ex)
	{
		return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
	}
	finally
	{
		ctx.Dispose();
	}
}

Now how we defined the routing attribute and prefixed it with “~” so Web API will route any HTTP GET request coming to the URI “api/subject/8/courses” to this route, this is really nice feature when you want to introduce exceptional routing in the same controller.

In the next post I’ll cover the IHttpActionResult return type as well the support for CORS in ASP.Net Web API 2.

Source code is available on GitHub.

The post What is New in ASP.Net Web API 2 – Part 1 appeared first on Bit of Technology.


Viewing all articles
Browse latest Browse all 37

Trending Articles