Building Web Services With Microsoft Azure - Sample Chapter
Building Web Services With Microsoft Azure - Sample Chapter
ee
P U B L I S H I N G
Stephen Kaufman
Alex Belotserkovskiy
Nikhil Sachdeva
Sa
pl
e
P r o f e s s i o n a l
E x p e r t i s e
D i s t i l l e d
Alex Belotserkovskiy
Nikhil Sachdeva
Stephen Kaufman
professional expertise distilled
P U B L I S H I N G
Background
Before we delve into the building blocks and design principles behind ASP.NET
Web API, it is important to understand that ASP.NET Web API is an evolution of the
existing continuous Microsoft efforts to enable support for HTTP Services. A timeline
of events that describe this evolution are outlined next.
Windows Communication Foundation (WCF) (https://msdn.microsoft.com/
en-us/library/ms731082%28v=vs.110%29.aspx) was launched with .NET 3.0 for
SOAP-based services; the primary aim was to abstract the transport layer and enable
support for the WS-* protocol. No HTTP features were enabled except HTTP POST
for requests
In NET 3.5, WebHttpBinding (https://msdn.microsoft.com/en-us/library/
system.servicemodel.webhttpbinding%28v=vs.110%29.aspx) was introduced
in WCF with the intent to support services that were not based on SOAP. It allowed
systems to configure endpoints for WCF services that are exposed through HTTP
requests instead of SOAP messages. The implementation was very basic and most
HTTP protocol features were still missing or needed to be coded separately.
WCF Starter Kit (https://aspnet.codeplex.com/releases/view/24644) preview
was launched to provide a suite of helper classes, extension methods, and Visual
Studio project templates for building and consuming HTTP REST-based services. A
new WebServiceHost2 type was added to host RESTful services. Also, client HTTP
support was added to provide a more natural experience for HTTP programming.
The project never got released and eventually migrated into WCF Web API. As of
August 2009 the project is in preview status.
During the same time, ASP.NET released some basic support to create REST APIs
with its .NET 4.0 release. Its capabilities were limited, and HTTP features such as
content negotiation were not available. ASP.NET was still targeted towards building
web applications.
WCF Web API (http://wcf.codeplex.com/wikipage?title=WCF%20HTTP) was
technically the first attempt to create a framework to support HTTP services from
the ground up. However, the development efforts still leveraged pieces from WCF
REST Starter Kit and .NET 3.5. A new rich, high-level HTTP programming model was
adopted that included full support for content negotiation. A variety of traditional
formats were supported (XML, JSON, and OData), and server-side query composition,
ETags, hypermedia, and much more was enabled. The development was simplified
by introducing the use of HttpRequestMessage and HttpResponseMessage to access
requests and responses. The WCF Web API's second release was compatible with
ASP.NET and allowed registering routes for Web APIs similar to ASP.NET MVC.
[ 16 ]
Chapter 1
The WCF Web API project merged with the ASP.NET team to create an integrated
Web API framework, and ASP.NET Web API was born. It shipped with the MVC4
Beta release in February 2012 and went to RTM in August 2012.
ASP.NET Web API 2 was released in October 2013 with new features such as
attribute routing and authorization with OAuth 2.0. Another version, 2.1, was
released in January 2014 with improvements to the existing infrastructure and
additional features such as global exception handling.
At the time of writing, ASP.NET Web API 2.2 is the current stable version of the ASP.
NET Web API framework. It includes more improvements to existing features such as
enabling client support for Windows 8.1 devices along with bug fixes.
Building blocks
As described in the previous section, ASP.NET Web API is built on top of existing
frameworks and technologies. Web API leverages features from ASP.NET MVC,
the core ASP.NET framework, and the .NET framework to reduce the overall
learning curve for developers and at the same time provides abstraction to make
programming easier. The following figure highlights the key features that make up
the ASP.NET Web API framework.
HTTP
programming
Model
Content
Negotiation
Help Pages
Self Hosting
Task Based
Async
Routing
Model Binding
Filters
Validation
Scaffolding
ASP.NET Framework
[ 17 ]
ASP.NET Web API leverages some standard features from the ASP.
NET MVC framework. Though expertise in ASP.NET MVC is not a
requirement for developing HTTP Services using ASP.NET Web API, a
fundamental understanding of the ASP.NET MVC framework and the
MVC design pattern is useful. More information about the ASP.NET
MVC framework is available at http://www.asp.net/mvc.
Russian Doll Model: This is also called the Matryoshka doll model, which
refers to a set of wooden dolls of decreasing sizes placed one inside the
other. Architecturally, it denotes a recognizable relationship of nested
objects (object within an object). The ASP.NET Web API messaging handlers
leverage this principle to define the request-response pipeline. Each handler
in the pipeline is responsible for processing the incoming request and then
delegating the request to another handler. When a request reaches a handler,
it may opt to process it, validate it, and then delegate the request to another
handler or break the chain by sending a response. Of course, this is not true
for the last handler in the chain since it will not delegate but rather work to
get the response back up the chain. The response will follow the same logic
but in the reverse direction and each handler will get the response before
sending it back to the caller. We will discuss message handlers in detail in
the next section. The follow figure describes the Russian Doll model being
employed by ASP.NET Web API framework.
[ 18 ]
Chapter 1
Handler 1
Handler 2
Handler n
Request
Response
Asynchronous to the core: The ASP.NET Web API leverages the .NET
Task-based Asynchronous Pattern (TAP) model to the core. TAP is based
on the Task and Task<TResult> types in the System.Threading.Tasks
namespace, which are used to represent arbitrary asynchronous operations.
TAP provides a new pattern to work with both CPU-intensive and non-CPUintensive asynchronous invocations. It simplifies the overall programming
model for asynchronous operations in .NET 4.5 through the async and await
model. Let's look at an example:
async Task<int> GetContentLengthAsync(string uri)
{
int contentLength;
using (var client = new HttpClient())
{
var content = await client.GetStringAsync(uri);
contentLength = content.Length;
}
return contentLength;
}
[ 19 ]
The return type for this method is Task<TResult>, the return type can also
be Task or void.
An async method typically includes at least one await call, which will mark
a path where the code cannot continue unless an asynchronous operation
is completed. It does not block the thread though. Instead, the method is
suspended and the control returns to the caller.
The method execution continues after the response is returned from the
asynchronous call.
A TAP-based pattern simplifies writing asynchronous programming
code and improves overall responsiveness of the system.
Application scenarios
As mentioned before, ASP.NET Web API enables customers to easily and rapidly
develop HTTP-based services that can result in new business opportunities or
improved customer satisfaction. Some of these scenarios are described here:
Mashup: This refers to accessing content from more than one service and
then creating a new service typically via a user interface. For example,
multiple services exposed by the Bing Maps API can be used by a consumer
to create a map-plotting user interface that can show the location of nearby
location on a map.
[ 20 ]
Chapter 1
Single Page Application (SPA): In this, all the necessary code artifacts
such as HTML, JavaScript, and CSS are retrieved in a single page load.
The appropriate resources are then dynamically rendered by making
asynchronous calls to services exposing data and functionality. ASP.NET
provides inherent support to populate JS frameworks, such as Knockout.js
and Angular JS, and provides full support for HTML5 and Web Sockets (via
SignalR). These technologies work together with the backend HTTP Services
layer built using ASP.NET Web API and Microsoft Azure websites to provide
a comprehensive solution to develop SPA.
Intranet and partner integration: When thinking about Web API, we usually
think about publically published APIs; however, there is much value in
developing Web API in a corporate or intranet scenario as well. If we go
back in history, one of the first Web APIs from Amazon was a byproduct of
the work they had been doing in their internal applications. Web API brings
reusability, and this brings down the development and testing cost when
dealing with multiple teams and large organizations.
Internet of Things: In the past year, Internet of Things (IoT) has become
the hottest buzzword. It is a phenomena bigger than anything that has
happened in the software industry since its inception. IoT coupled with cloud
technologies enables scenarios that never existed. For example, a thermostat
talking to a cloud service and providing telemetry data to the manufacturer
can open avenues of new businesses via predictive maintenance using data
analytics or partner integration to provide better customer service. As devices
are becoming more powerful, they are no longer restricted to short-range
networks or lightweight protocols. HTTP infrastructure and Web APIs can
play a pivotal role in such scenarios in the coming years.
[ 21 ]
To install the runtime packages via the NuGet Package Manager Console in Visual
Studio use the following command:
PM> Install-Package Microsoft.AspNet.WebApi
Alternatively, Visual Studio provides a NuGet user interface dialog that can be used
to install the package. For more information on using the NuGet dialog in Visual
Studio, visit https://docs.nuget.org/consume/package-manager-dialog.
Note that a project created using the ASP.NET Visual Studio 2013
template does not require adding these packages explicitly.
[ 22 ]
Chapter 1
The following figure describes the core assemblies and their dependencies that get
downloaded when the Microsoft.AspNet.WebApi package is installed. There are
other NuGet packages that are published by the ASP.NET Web API team (such as
CORS support, Help Pages, OWIN host). This figure provides the bare minimal to
get started with ASP.NET Web API development:
JSON.NET
popular high performance JSON
framework for .NET
Newtonsoft.Json
Microsoft.AspNet.WebApi.Client
adds support for formatting and
content negotiation to
system.Net.Http. It includes support
for JSON, Xml and form URL
encoded data
System.Net.Formatting
Microsoft.AspNet.WebApi.Core
core runtime libraries for ASP.NET Web
API. It is used by hosts of the ASP.NET
WEB API
System.Web.Http
System.NET.Http
provides access to HttpClient and
other common HTTP functionality
System.Net.Http
Microsoft.AspNet.WebApi.Host
Microsoft.AspNet.WebApi.SelfHost
Microsoft.AspNet.WebApi
facade package which adds addiction
metadata properties for creating HTTP
Services using ASP.NET Web API
None
Now, let's look at some of the important runtime types that enable the
communication and execution in the ASP.NET Web API pipeline.
DelegatingHandler
As mentioned earlier, the execution of a request implements a Russian Doll Model.
A DelegatingHandler is a runtime type that enables the creation of a handler that
can participate in the chain of request and response pipeline for ASP.NET Web API.
Although used heavily by the ASP.NET Web API infrastructure, DelegatingHandler
is a type defined in System.Net.Http.
[ 23 ]
base class for all HTTP message handlers. The most critical method exposed by
thus enabling a chain between the handlers. Any type that inherits from
DelgatingHandler can then participate in the pipeline by ensuring that SendAsync
on DelgatingHandler is called.
public class CustomMessageHandler: DelegatingHandler
{
protected async override Task<HttpResponseMessage>
SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
// Call the inner handler.
var response = await base.SendAsync(request,
cancellationToken);
return response;
}
}
All message handlers in ASP.NET Web API are contained in an ordered collection
as part of the HttpConfiguration.MessageHandlers collection. What this means
is that the handlers are always executed in sequence of their addition. The ASP.NET
Web API framework allows for defining message handlers at the configuration level
on a per route basis using HttpRoutingDispatcher. We discuss more details about
this feature in the Routing and dispatching section.
[ 24 ]
Chapter 1
HttpRequestMessage
HttpRequestMessage is a runtime type defined in the System.Net.Http namespace;
it acts as an unified abstraction for all HTTP requests irrespective of client or server.
Any incoming message is first converted into HttpRequestMessage before it
traverses through the pipeline; this provides an ability to have a strong type HTTP
message throughout the pipeline.
Description
Content
Headers
This contains all headers in the HTTP request. These can be used to
retrieve authorization headers and user agents. The Content property
also exposes a Headers collection, which is useful to define header values
for the content itself, such as ContentType and MediaFormatters.
Properties
This specifies the method of the request (GET, POST, PUT, DELETE,
OPTIONS, TRACE, HEAD) and returns an HttpMethod type.
HttpResponseMessage
HttpResponseMessage represents the other side of the story and provides an
abstraction for all responses generated for corresponding HTTP requests. It is also
defined in the System.Net.Http namespace. Any response within the pipeline will be
represented as HttpResponseMessage before it gets converted and sent to the caller.
HttpResponseMessage may contain values for the following attributes:
Name
Content
Description
Headers
RequestMessage
IsSuccessStatusCode
[ 25 ]
Name
StatusCode
Description
ReasonPhrase
Version
ApiController
ASP.NET MVC has the concept of controllers since its inception; conceptually,
Web API controllers follow a similar approach to leverage the goodies from the
ASP.NET framework. However, Web API controllers are targeted towards providing
an abstraction over the HTTP request-response pipeline. Moreover, Web API
controllers return only response data in contrast to HTML views in ASP.NET MVC.
All Web API controllers implement the IHttpController interface to classify them
as Web API controllers. As we will see in the next section, the Web API request
dispatch, and route matching pipeline attempts to look for an IHttpController
instead of a particular controller implementation. The following code snippet shows
the definition for the IHttpController interface.
namespace System.Web.Http.Controllers
{
public interface IHttpController
{
Task<HttpResponseMessage>
ExecuteAsync(HttpControllerContext
controllerContext, CancellationToken cancellationToken);
}
}
[ 26 ]
Chapter 1
The series of actions performed by the API controller in the preceding code
is as follows:
1. The API controller invokes the action selection logic for the HTTP request.
2. It then initializes and invokes the registered authentication filters.
3. Subsequently, it initializes and invokes the authorization filters.
4. Next, the action filters are initialized and invoked followed by the exception
filters in case of exceptions.
5. In the last step, it invokes the Parameter Binding and content negotiation for
the requests and responses.
Finally, the operation is executed.
[ 28 ]
Chapter 1
Description
HttpControllerDispatcher
System.Web.
Http
HttpControllerContext
System.Web.
Http
HttpParameterBinding
System.Web.
Http
IContentNegotiator
System.Web.
Http
IHttpControllerSelector
System.Web.
Http
HttpActionSelector
System.Web.
Http
HttpControllerHandler
System.Web.
Http
[ 29 ]
Assembly
System.Web.
Http
Type
MediaTypeFormatter
Description
HttpServer
Assembly
System.Web.
Http
System.Web.
Http
We will get into the details of most of these types in later sections and in Chapter 2,
Extending the ASP.NET Web API.
Message lifecycle
Now that we have some context of the main APIs involved in the Web API
request-response pipeline, let's take a look at how a request flows through
the Web API pipeline and how a response is directed back to the client.
At a broad level, the message pipeline can be categorized into three main stages:
Host Listener
Controller Processing
Let's walk through the message pipeline using a sample Web API. The Web API is
a simple Hello World API that allows the client to issue a GET request and returns
the string Hello world! in JSON. For now, don't worry about the implementation
details of this Web API. In the next sections, we will get into deeper detail on how
to create, test, and deploy a Web API.
Request
http://localhost:12356/api/hello
Response
Hello world!
[ 30 ]
Chapter 1
Host listener
A host listener refers to a component listening for incoming requests. For years,
Microsoft Web Components had an inherent dependency of using Internet
Information Services (IIS) as the host. The ASP.NET Web API breaks out of this
legacy model and allows itself to be hosted outside IIS. As a matter of fact, we can
host a Web API in an executable, which then acts as the server receiving requests for
the Web API. There are many options available to host a Web API; we will explore
some of them in detail in Chapter 2, Extending the ASP.NET Web API. For now, we
will focus on using either of the hosting options and enable listening for requests
and responding with a response.
Considering the earlier Hello World example, the incoming request will be processed
as shown in the following diagram:
GET http: localhost:12356/api/hello HTTP/1.1
Host: localhost:12356
IIS Host
HTTP Request
HTTPRequestMessage
{}
HttpServer
OWIN
HTTPResponseMessage
HTTP Response
client code
Web Server
HTTP/1.1 200 OK
Content-length: 15
Content-Type: application/json; charset=utf-8
server: Microsoft-HTTPAPI/2.0
Self host
Host Listener
Hello, world!
2. The configured host listener will then receive the request and convert it into
HTTPRequestMessage. The host inherits from the HTTPServer type, which
by itself is a message handler and implements DelegatingHandler. So,
essentially it is just another message handler that delegates the request to the
next handler (remember the Russian Doll Model we talked about earlier).
3. The request is then sent through to the routing and dispatching components
and then to the controller components for further processing and returning
the response.
[ 31 ]
[ 32 ]
Chapter 1
name: "CustomDefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: null,
handler: new CustomMessageHandler()
);
}
[ 33 ]
Route.Handler
DelegatingHandler
HttpMessageHandler
HTTPRequestMessage
Host Listener
(HttpServer)
HttpRoutingDispatcher
Route.Handler
--NULL?
HttpControllerDispatcher
HTTPResponseMessage
SelectController
HttpControllerDispatcher
HttpControllerSelector
HttpControllerTypeResolver
HttpControllerActivator
HttpControllerContext
CreateController
[ 34 ]
AssembliesResolver
Chapter 1
Controller processing
The final and the most exciting stage of the pipeline is processing the request by
the controller; this is where all the magic happens to generate the appropriate
response for the incoming request. As explained earlier, if the controller inherits
from APIController, much of the plumbing work is already abstracted from the
developer. The following pipeline walks through a controller pipeline that inherits
from APIController:
1. The controller first determines the action to be invoked:
actionDescriptor = ServicesExtensions.
GetActionSelector(services).
SelectAction(controllerContext);
AuthenticationFilters
Controller
AuthorizationFilters
[ 35 ]
ExceptionFilters
FormatterParameterBinding
ComplexType
HttpRequestMessage
HttpRequestMessage
SimpleType
ModelBinderParameterBinding
IValueProvider
HttpRequestMessage
HttpParameterBinding
AnyType
4. Next, the pipeline executes the actual action and any associated action filters.
This will process the code that we write in our action method for processing
incoming requests. The framework actually provides an ability to execute the
action filters as a pre and post step to the actual method execution.
Controller
OnActionExecuting
ActionFilters
invokeActionAsync
ControllerAction
OnActionExecuted
ActionFilters
5. Once the controller action and the post filters are executed, the final step is to
convert the response generated into an appropriate HttpResponseMessage
and traverse the chain back to return the response to the client. This is shown
in the following figure:
[ 36 ]
Chapter 1
HttpRequestMessage
Controller Action
Response
type?
void
HttpResponseMessage
StatusCode: 204
passthrough
No content
HttpResponseMessage
HttpRequestMessage
ExecuteAsync
Invoke executeAsync
Serialize type
HttpRequestMessage
IContentNegotiator
MediaTypeFormatter
Prerequisites
The following must be configured to run the example scenarios we discuss in this
and following chapters:
Visual Studio 2013: Once we have the virtual machine up and running, we
will need Visual Studio 2013. Any version of Visual Studio Professional 2013
or later should be sufficient for our samples. There is also a free full feature
version of Visual Studio referred to as Community Edition, which enables
ASP.NET web development. MSDN subscribers can also get access to a set of
preconfigured Visual Studio virtual machine images available as part of the
Microsoft Azure subscription. The source and samples for this book are built
using Visual Studio 2013 Community Edition Update 4.
A free Visual Studio Online account can be created at the following link: https://
www.visualstudio.com/en-us/products/what-is-visual-studio-online-vs.
aspx. To know more about using Git with Visual Studio Online, visit the following
link: https://msdn.microsoft.com/en-us/library/hh850437.aspx.
An alternative is to use GitHub as a source control strategy as well. For the purpose
of this book, we will use VSO and Git.
Now that we have the development tools installed and ready, let's quickly take an
example to put these to test. We will build an ASP.NET Web API for a fictitious
transport service provider that provides consumers with package tracking abilities.
The following figure shows how clients interact with the solution:
{}
Client Agents
Controller(s)
http://api.cloudapp.net/
api/resource
Respository
{JSON}
Model(s)
</>
Scripts
[ 38 ]
Existing
Data Store
Chapter 1
[ 39 ]
Also, we unselect Host in the Cloud under Microsoft Azure for now. We will add
this in the next section when we talk about the Microsoft Azure website.
[ 40 ]
Chapter 1
A few things have been added to jump start our Web API project:
A static WebApiConfig type has been added to the App_Start folder. The
WebApiConfig.cs file is responsible for registering configuration settings for the
Web API during startup. Some of the common uses of WebApiConfig.cs are to
define default routes, customize the behavior of global and per route matching
routes, and define media type formatters.
An important thing to note is the Register method that contains the following code:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
This method defines the default route template for any request; what this means is
that any request that has a route api/{controller}/{id} will be considered a valid
route. In this route we have the following parameters:
{id}: This is used for parameter binding, these together define the controller
With Web API 2, we now have the option to specify attribute-based routes on each
API call to provide granular route definitions for our Web API. We will cover this
in more detail in Chapter 2, Extending the ASP.NET Web API.
The Global.asax file has the following defined in Application_Start, this registers
a delegate for the WebApiConfig.Register method in GlobalConfiguration. Note
that GlobalConfiguration belongs to System.Web.Http.WebHost, which indicates
that we are currently hosting our Web API in IIS, as shown:
GlobalConfiguration.Configure(WebApiConfig.Register);
For the scope of this chapter, we will keep the data access very simple. We will
have an in-memory store and will define an ASP.NET model to represent it. In later
chapters, we will fetch data using tools like Entity Framework and also discuss how
expose OData endpoints for building query capabilities from our Web APIs.
We follow these steps to create an ASP.NET model for our solution:
1. Right-click on the Models folder. Click on Add and then on New Item.
2. From the Add New Item dialog, add a new C# class. Name it Package.cs.
3. Add properties to the data model. The package data model should look
like this:
namespace Contoso.Transport.Services.Models
{
public class Package
{
public int Id { get; set; }
public Guid AccountNumber { get; set; }
public string Destination { get; set; }
public string Origin { get; set; }
public double Weight { get; set; }
public double Units { get; set; }
public int StatusCode { get; set; }
}
}
Chapter 1
[ 43 ]
[ 44 ]
Chapter 1
Id = 3,
AccountNumber = Guid.NewGuid(),
Origin = "FL",
Destination = "GA",
StatusCode = 3,
Units = 1,
Weight = 2.5,
Created = DateTime.UtcNow,
}
};
}
}
}
The return type here is our Package entity, when a response is generated, ASP.
NET Web API will serialize the entity using the MediaFormatter configured for
the project. To facilitate control over the HTTP Response, ASP.NET Web API also
provides additional types such as IHttpActionResult and HttpResponseMessage.
We discuss these in Chapter 2, Extending the ASP.NET Web API.
The signature of the GET operation matches HttpRoute that we defined in the
WebAPIConfig.cs file (api/{controller}/{id}). The signature allows us to
determine which HTTP verb needs to be executed for the incoming request. We may
define multiple operations for a controller, but each needs to match to a particular
route. This approach is also referred to as routing by convention. If no route is
found, an exception is thrown. ASP.NET Web API 2 also provides specific routes
per controller or even per action through attribute routing. We will discuss these
approaches in detail in Chapter 2, Extending the ASP.NET Web API.
[ 45 ]
Next, build the project and that is it! We just created our first Web API. We now
have a controller that can search for packages based on IDs and return the package
model as a response. In the next section, we put our Web API to test in order to
verify our operations.
Testing in a browser
Testing a Web API is as simple as developing it, since each action in a Web API
controller represents a resource, we can just type the URL of the resource and fetch
the results.
1. Press F5 in Visual Studio to launch the Web API in a browser.
2. Visit the following URL:
http://localhost:<PORT>/api/package/1
Note that the port will be allocated by IIS Express and will
be different for each installation.
[ 46 ]
Chapter 1
When the server received the request, it scanned all controllers to check for a
matching route. When the route was found, PackageController was selected to
respond to the request, and its Initialize method was invoked. The GET action in
PackageController was then identified as a route match for the HTTP GET request.
The method gets called, and 1 is passed as the parameter.
System.Net.Http assembly
Contoso.Transport.Services
Newtonsoft.JSON
Newtonsoft.Json;
System.Threading.Tasks;
System.Net.Http;
Contoso.Transport.Services.Models;
namespace Contoso.Services.Tests
{
[TestClass]
public class PackageControllerTests
{
[TestMethod]
public async Task FindPackageByIdNotNullTest()
{
var packageid = 1;
var packageUrl =
string.Format("http://localhost:
<PORT>/api/package/{0}", packageid);
using (HttpClient client = new HttpClient())
{
var response = await
client.GetStringAsync(packageUrl);
Assert.IsNotNull(response);
var package = await
Task.Factory.StartNew(() =>
JsonConvert.DeserializeObject
<Package>(response));
Assert.IsNotNull(package);
Assert.AreEqual(packageid, package.Id);
}
}
}
}
[ 48 ]
Chapter 1
We verified our Web API using a .NET client as well. HttpClient exposes a set of
utility methods that allow us to perform various HTTP operations. In this case, we
used the GetStringAsync method that creates an HTTP GET request and returns the
response as a string.
[ 49 ]
We will now commit the change to Visual Studio Online. Visual Studio 2013
provides a rich integration with Git so we can commit the changes without
opening the Git command prompt:
1. Right-click on the Contoso.Transport.Service solution file in the
Solution Explorer, and click on Add Solution to Source Control.
2. A dialog box is displayed with options for available source control systems.
Select Git and click on OK.
3. Right-click on the solution again and click on Commit.
[ 50 ]
Chapter 1
4. Enter comments for the changes, and click on Commit to create a local commit.
5. We can now use the Sync/Push Git commands from Visual Studio to
commit our changes remotely:
There are other PaaS offerings available in Microsoft Azure, such as cloud services
that provide Web and worker roles. There is also Microsoft virtual machine through
the Infrastructure as a Service (IaaS), so why choose websites?
[ 51 ]
Let's look at some of the features provided by Azure Websites, which make them an
appealing candidate for Web API and web app deployment:
Network share support: All instances can leverage shared content storage,
this ensures optimum reliability in case the frontend machine goes down.
Stateless servers and smart load balancing: Following the cloud design
patterns, all VMs are stateless by design.
SQL
W3wp.exe
Hosting Sites DB
Site Content DB
Metering
SQL
DWAS
Provisioning API
Azure Drive
Storage Controller
[ 52 ]
10
01
Chapter 1
As we can see in the preceding figure, Azure Websites are built on existing
technologies, such as Azure storage and web and worker hosting model. It
adds additional abstraction to enable rapid deployment and easy configuration
management through a set of hosting site and site content databases. Furthermore,
Azure load balancers are used in conjunction with IIS Application Request Routing
(ARR) load balancers to achieve high availability and Hyper Scale. Azure Websites
provides the following benefits:
Built for DevOps: Azure Websites are targeted to reduce the overall time
taken to market and provide an effective TCO. Some of these features include
high available environment with automatic patching support, automatic
scale, automatic disaster recovery and backups, comprehensive monitoring
and alter, and quick and easy deployment.
With such great features, is there any scenario where Azure Websites might not be a
good fit?
Well, there are some scenarios where we may be better off using Azure Cloud
Services and perhaps even Azure Virtual Machines:
In-role cache: Due to the stateless nature of Azure Websites, in-role caching
is not supported. However, we can use a distributed cache such as Redis and
make it work with websites.
Note that some of the scenarios mentioned here might not be available as of today,
but the team may provide support for these in future releases. As a rule of thumb,
consider these as recommendations and not protocols. Considerable planning
should be conducted based on customer requirements and timelines before making a
decision to choose any of the platform options.
Since we did not associate our Web API project to an Azure Website at the time of its
creation, we will now provide details on the Azure subscription and website where
we want the deployment to be hosted:
1. Right-click on the Web API project. Click on Publish to open the Publish
wizard, and select Microsoft Azure Websites as the publish target.
[ 54 ]
Chapter 1
2. In the Microsoft Azure Websites dialog, click on New to create a new Azure
Website. Here, we provide details about our Azure subscription and give a
name to the website. When deciding on a name, ensure that it is unique; the
Create Site dialog box validates the fully qualified URL to ensure that there
are no existing sites with this name. In case the site name already exists, an
error is thrown by the Create Site dialog box.
3. By default, the domain name is set to azurewebsites.net. It is the
default domain for all tiers; we can also provide a custom domain
for our deployments (for example, www.mywebsite.com).
[ 55 ]
4. Once the Website is created, we are ready to publish our Web API. Azure
Websites provides the following publish methods for web applications:
5. Once the deployment is complete (should not take more than a few seconds),
we will have our Web API running in the cloud.
6. To test the deployment, replace the local domain name we used in the
Testing in a browser section with the cloud domain name of the Azure
Website as shown:
Request
Response
http://dotnetbook.azurewebsites.net/api/package/1
{
"Id": 1,
"AccountNumber": "ac09ae02-00cf-426db969-909fae655ab9",
"Destination": "TX",
"Origin": "CA",
"Weight": 2,
"Units": 1,
"StatusCode": 1,
"History": null,
"Properties": null
}
If we now browse to the Azure management portal and go to the Azure Website we
just created, we can right away see incoming requests and how the traffic is being
monitored by Azure Websites similar to how it is shown in the following diagram;
now that is true PaaS!
[ 56 ]
Chapter 1
[ 57 ]
2. Select VSO to designate the source code and then select the repository
to deploy:
Azure will now create a link to Visual Studio Online. Once the link is
established, when a change is committed, it will get deployed to Azure
Website automatically. The link creates a build definition for the solution and
configures it to run in CD mode. If we go to the build definition in Visual
Studio, we can see that a new build definition is added. The linkage also
sets the deployment attributes for the build. It ensures that a commit on the
solution triggers a deployment. Note that if any unit test projects, which are
part of the solution will also automatically get triggered.
[ 58 ]
Chapter 1
3. Let's make a change to our existing sample to verify this. We will add a
new attribute to our Package ASP.NET data model that we created earlier.
This attribute will get populated with the current UTC timestamp when the
package is created:
namespace Contoso.Transport.Services.Models
{
public class Package
{
public int Id { get; set; }
public Guid AccountNumber { get; set; }
public string Destination { get; set; }
public string Origin { get; set; }
public double Weight { get; set; }
public double Units { get; set; }
public int StatusCode { get; set; }
public DateTime Created { get; set; }
}
}
[ 59 ]
4. When we make a commit and push to the Visual Studio Online repository,
the build definition will invoke a new build, which will also update the
deployment in our existing Azure Website. This can be verified by looking at
the build report:
[ 60 ]
Chapter 1
5. Now, if we again call the same end point, we should get the Created
attribute as part of the response:
Request
http://dotnetbook.azurewebsites.net/api/package/1
Response
{
"Id": 1,
"AccountNumber": "48e89bcd-cfaa-4a47a402-9038ca2dd69b",
"Destination": "TX",
"Origin": "CA",
"Weight": 2.5,
"Units": 1,
"StatusCode": 1,
"Created": "2014-0914T22:17:32.8954157Z",
"History": null,
"Properties": null
}
Our Web API is now successfully deployed in Microsoft Azure Website and
configured for CD.
Summary
This chapter provided an overview of the what, why, and how of an ASP.NET
Web API. ASP.NET Web API is a next generation service that enables support for
a first-class modern HTTP programming model. It provides abundant support for
formats and content negotiation, and request validation.
We talked about the foundational elements of a Web API. We then discussed its usage
scenarios and components, and also discussed the classes that make up the API. We
went through the request-response pipeline and walked through the message lifecycle
of a request. We then created our first simple Web API for a simplified customer
scenario and walked through its development, testing, and deployment using Azure
Websites. In the next chapter, we will look into advanced capabilities of ASP.NET Web
API, and see how these capabilities can be used to customize different aspects of the
ASP.NET Web API request-response pipeline.
[ 61 ]
www.PacktPub.com
Stay Connected: