Showing posts with label Attribute Routing. Show all posts
Showing posts with label Attribute Routing. Show all posts

Thursday, January 16, 2014

Self Hosting ASP.Net Web Api Service with OWIN - Katana

In the previous post, we looked at hosting ASP.Net Web API application using Microsoft.Aspnet.WebApi.SelfHost package. With this post, we are going to start looking at how we can host the same service using Katana. It's an interesting name, isn't it? Already feeling like a Samurai :)

OWIN is a Microsoft's specification for web applications. Open Web Interface for .Net. OWIN specification provides layers of host, server, framework and your application. So the same host and server can be used to host a number of applications with different frameworks. They would be part of same pipeline. So we can also hookup infrastructure and security components on the front re-using them for all of these applications. Since this is a composable architecture, you are building the whole pipeline. This is unlike other hosting stories.



As stated by Microsoft, Katana is an OWIN implementation by Microsoft. It is an attempt to decouple web applications from servers. This should enable hosting of web applications including Web API, Signal R and front-end applications without requiring IIS. This should allow a combination of hosts and servers for hosting an application developed using a particular framework including ASP.Net Web API.



Let's create a console application for hosting InstituteService we have been continuously developing. We name the project as InstituteService.Host.Console.Owin. It's just a three steps process after this.

Step I: Let's first install the required Nuget package required for OWIN Self Hosting. Here we are installing Microsoft.AspNet.WebApi.OwinSelfHost package.



As is general with Nuget packages, it should install all the required Nuget packages for the package installation.



Although OWIN is specified as a specification, there is also Owin.dll. The assembly just contains IAppBuilder. In order to host it, we need to implement a type. Here we have a type named Startup. As a convention, the type needs to have a method Configuration with a single parameter of type IAppBuilder. This is Step II. Actually, you compose the whole application stack here. Here UseWebApi is an extension method defined for IAppBuilder. This is the whole idea, all application you want to host would involve a nuget package installation for the framework. The package would generally provide an extension method like we have UseWebApi here. The method is passed with an HttpConfiguration instance. We are configuring it for attribute routing.


For Step III, now we need to host the service. The package provides WebApp type. The type provides a generic method Start with a type parameter as the type declared above.


And that's it!!! Now we can run the application. It would host the service and wait for a key to be pressed, then it exits the application. It shows up as the following console screen:



Here we are accessing the service. Since we configured the application with Attribute Routing, it would determine the correct action based on controller's route prefixes. Since we have requested the response in text/json format, the content-negotiation with server with the server would result in the same format. Please remember that ASP.Net Web API JSON.Net for this purpose by default (if I remember it right).

Saturday, December 14, 2013

ASP.NET Web API 2 - Action's Response and IHttpActionResult

This is a continuation of our discussion about ASP.NET Web API. In this post we are trying to understand how results generated by actions are interpreted and further processed by ASP.NET Web API message pipeline. In the previous posts, we have defined various actions with three different types of returned data. There are following return types you might see for Web API action implementations:
  1. HttpResponseMessage
  2. IHttpActionResult [ASP.NET Web API 2]
  3. Any other type
  4. void
Every ASP.NET Web Api requests passes through a pipeline before a particular controller's action is invoked. The action's response can also be processed and passed through various stages before it is pushed to the requester. This is also possible that all the formatting is done at the action's side generating an HttpResponseMessage, resulting in bypassing all these stages. At the end, irrespective of returned data, an HttpResponseMessage is generated.



ASP.NET Web API message life cycle poster can be obtained from Microsoft's download center. If you understand the flow of message as described in this poster then you understand it all. So make sure that all the particular pieces are looked at with great emphasis and care.



Return type as void
These are the simplest of all actions from development perspective. They are specially useful for the requests with HTTP verbs including PUT / DELETE and POST. In these cases, the client is not interested in the data returned form the service. They are for pushing data to the service. Let's just make sure that having a return type as void doesn't mean nothing is being returned to the client and still an HttpResponseMessage is generated.

Returning Domain Object
This is the simplest and easiest of all options. Here we treat our actions invocations as regular methods calls. We return domain objects from these actions. In this way, our actions' code is not populated with the HTTP based types. It is the framework's responsibility to create an HTTP response including the returned data as value.


It is for these actions, that framework hooks up the injected MediaTypeFormatter (s) and Content Negotiators based on the media types requested by client and type of data being returned. After data is passed through these stages, an HttpResponseMessage is generated and returned to the client.

Returning HttpResponseMessage Directly
This is another option allowed for Web API actions. Here the API takes the responsibility for creating the response on its own making it easier for the framework handling the response message. As a developer, we have the flexibility for controlling the HttpStatusCode generated with the response.


As you can see here, in addition to the data, we are specifying the HttpStatusCode for the returned response. We are using the value OK (= 200).

IHttpActionResult Interface & ASP.NET Web API 2
Here we are neither generating the domain objects directly nor we are handcrafting the HttpResponseMessage directly in ApiController's actions in a synchronous fashion. Instead, we are returning a response held by a type implementing IHttpActionResult interface. ASP.NET Web API 2 introduced IHttpActionResult in order to support asynchronous generation of HttpResponseMessage.



It also introduced a number of implementations of the interface in System.Web.Http.Results namespace in System.Web.Http assembly.



ApiController has also been updated with a number of additional methods returning such results. They make it easier for generating the response. They also include the appropriate HttpStatusCode with the response based on the method being used. These methods are supposed to be used from ApiController's actions to generate a response. The value obtained from these methods can simply be returned by the controller's action method.



The following is an example action supporting HTTP Post method. The action accepts student's data from the request body. After writing the data to the console, it generates an HTTP OK for the requesting client.


Let us see how our service responds to a request invoking the above action. In order to keep the example simple, the action is not doing much other than just writing the student's data to the console. It is also generating an OKResult (implements IHttpActionResult) by calling the Ok() method defined in ApiController type.



We can also provide custom implementation of the interface and use them in Web Api actions.

Returning Errors
The actions with return type as void or any other type other than HttpResponseMessage has only one way to return an error response i.e. to throw an exception in the event. The exception is caught by the framework pipeline and an appropriate error response is generated.



On the other hand the actions returning HttpResponseMessage can always generate error responses. Here we are using Request property of ApiController. This is of type HttpRequestMessage.


If this is a web client, the error is displayed in the browser as follows:



For the actions returning IHttpActionResult, we can always return different implementations of the interface based on the underlying condition. In case of error we may also use the methods added in ApiController for such conditions.

Sunday, December 8, 2013

Attribute Routing in ASP.NET Web API 2

In the previous post, we discussed about HTTP routing in ASP.NET Web API. With version 2, Microsoft has incorporated a more flexible version of routing into the API. This is called Attribute Routing. The feature is contributed to ASP.NET MVC project by Tim McCall [http://attributerouting.net/]. Conventional routing supports defining the routes on global level. Since attribute routing allows defining routes on controllers and their actions, it provides extraordinary flexibility in defining these routes. The feature can be used to define resource hierarchies in the same controller.It also enables us to define options parameters, default values and resource and parameter constraints.

Enabling Attribute Routing
Let's first create an ASP.NET Web API project. Let's name this project as InstituteService.



Attribute Routing is included in ASP.NET Web API 2. Visual Studio 2013 supports creating ASP.NET Web API 2 based projects out of the box. We can also create then in Visual Studio 2012 with the help of Microsoft.AspNet.WebApi.WebHost nuget package.



The service is required to provide information about students and their courses. Here we are introducing types Student and Course to hold information about students and courses respectively. Each course maintains a list of students attending the course.

We need to update Web API configuration to use Attribute routing. The configuration is done in WebApiConfig. The new version of ASP.NET Web API has introduced a new version in HttpConfiguration type with an extension method MapHttpAttributeRoutes. We need to update the code to use this method instead.



Now let us add an empty controller for our Institute service. Here we are creating it as an empty API Controller.



As we have discussed in previous posts, a Web API controller inherits from ApiController type from System.Web.Http.



Now let us seed some data which could be returned from the service. In order to keep the example simple, let us create some data in the service constructor. Here we are creating three students assigned to two different courses. The first course is assigned with all the three students when the second course is just being attended by Muhammad and Roosevelt.


Defining Routes Using [RoutePrefix] & [Route] Attributes
ASP.NET Web API 2 support defining routes by introducing RoutePrefix and Route attributes. The RoutePrefix attribute can be used on controllers. This allows definition of a default prefix for all the actions in the controller.


Now we can add relative routes to individual actions. The routes are defined on actions using [Route] attribute. Here we are adding two actions to provide the list of course and students of the institute.


The above actions can be used to fulfill client request as follows:



Parameterized Routes
In the previous post we discussed how parameterized routes can be used for Web API resources. For conventional routing only certain parameters can be used as part of the request routes. For any additional parameters, we had to use query parameters. Since attribute routes are defined on individual actions, we can use action parameters for parameterized routes. In the following example, we are using courseId as route parameter. This is one of the parameter of the action defined below:


The above action can be used with the following request. As you can notice, the client is requesting all the students attending course (CourseId = 2). This course is only being attended by Muhammad and Roosevelt.



Route Constraints
Attributes routes also supports constraints. The list of constraints can be found on msdn (route constraints). In the following example we are defining two actions. The first actions is providing the list of courses being attended by a student identified by StudentId parameter. In this case, the constraint is defined to check that the Id must be an integer value. This is achieved using int contraint. For the second action, the same can be requested using student's name as parameter. Here we are using alpha constraint. This is to make sure that the name only include alpha characters. The same can be achieved using regex constraint (commented).


Let's see how we can request the above resources. Here the service is returning the list of courses attended by Muhammad. As you can notice, the returned data also includes the list of all students attending the courses. You might want to create a different type to return the course data to clients.



ASP.NET Web API 2 also supports defining custom constraints. It provides IHttpRouteConstraint interface in System.Web.Http.Routing namespace. We need to provide definition for Match method of the interface. The constraint is considered passed when the method returns true.

Default Values for Optional Route Parameters
Web API 2 also supports optional route parameters. They are identified with a question mark followed by the parameter name. The parameters are still identified with the brackets (e.g. {studentId?}). The default values can be specified as a method parameter as we generally specify for optional parameters for a method. In the following example, we are defining an action with studentId as a optional route parameter. The default value for the parameter is 1, so it would be returning all the courses attended by Muhammad.


The other option to define default values is by including the default value as part of the route. In order to get the same behavior as above, we can define the route as follows:


Although the behavior seems to be same for the above two examples, but they are a little different in the way they work out the value for the optional parameter in case one is not specified in the client request. The first example just causes the action to be used in case the parameter is not specified, and the value for the parameter is through optional parameter for C# method. For the second example, ASP.NET Web API framework is responsible for assigning value for the parameter. This is done through the model binding process. We can also define our custom model binder but lets just keep it for some other post.

Versioning Resources
ASP.NET Web API 2 also makes it super easy for versioning the API. As we have discussed before we might not want to expose the list of students who are signed up for a particular course when we return the course attended by a particular student. Here we are just introducing a new type for holding courses with the details including Id and its name.


We can use this type to introduce a new version for such requests. Here we have just added a literal in our resource route url. We can use the same for all actions exposing the same version of types to our clients.


We can use the above action using the same route prefix as we define on the Api controller. Here we are using the same Api by exposing a different version of Course type to clients.



Overriding RoutePrefix for Actions
We have been discussing how we can define routes for Web API actions. The specified route on actions is used with the route prefix defined on controller level [RoutePrefix attribute]. What if we want to override the route on some of these actions. ASP.NET Web API 2 supports this. This is defined using tilde (~) character. In the following example, we are doing the same thing:


Now we don't need to use the route prefix defined on the controller. We can access the resource provided by the above as follows:



Route Order and Precendence
Since the routes are defined on the actions themselves, it is natural to wonder what would happen if there are multiple actions qualify for the same URL. This is very common when optional route parameters are used. In the following example we have two actions with actions annotated with independent routes overriding route prefixes.


Now which of these action would be used when we use the URL below. It seems that the first action is being used. But why?



As a matter of fact, there is a particular logic for route precedence for these actions. There are certain ASP.NET Web API rules in action. And these rules are being applied here causing the first action to be used for the request. So now we know why this is happening whatever is happening. But we are interested in knowing what these rules are. The following is copied from msdn.



So in the case of our example, since the first action is annotated with literal route, it is taking precedence on the route defined on the other action with parameterized route. As is apparent from the above rules, we can override this order by defining an explicit RouteOrder on the actions.


Now if we use the same URL, we are definitely hitting the second action as follows:



Download