The wrox.com
code downloads for this chapter are found at www.wrox.com/go/beginningvisualc#2015programming
on the Download Code tab. The code is in the Chapter 17 download and individually named according to the names throughout the chapter.
Now that you have spent some time learning about the cloud and cloud programming, let's move forward and write some C# code that is a little more complex than what you did in the previous chapter. In this chapter, you continue exploring both ASP.NET and Microsoft Azure. You will modify the CardLib
program so that it runs in the cloud as an ASP.NET Web API and, once deployed, you consume it from an ASP.NET Web Site.
After creating, deploying, and consuming the ASP.NET Web API, you will learn how to scale it. The concept of scaling is important to grasp in the event that the cloud program you create becomes popular. The example in this chapter uses free Microsoft Azure cloud resources. These free resources have low CPU, memory, and bandwidth thresholds and are easily breached under high usage. You will learn how to avoid any suspension of your cloud program due to resource threshold breaches by scaling when appropriate.
The Application Programming Interface (API) computer programming concept has been around for many decades and is generally described as a module that contains a set of functions useful for building software programs.
Originally, from a Windows client application perspective, these modules were dynamic linked libraries (.dll
) and exposed programmatically accessible interfaces that exposed internal functions to other programs. In such a system, when a consuming program uses an API, it becomes dependent on the pattern of the interface. Changes to the interface cause exceptions and failures within the consuming program because the current procedure to access and execute the functions within the module is no longer valid. Once programs become dependent on an interface, it shouldn't be changed and when it is changed the event is commonly referred to as DLL Hell. For more information about DLL Hell, read this article: http://www.desaware.com/tech/dllhell.aspx
.
As time moved on and the implementation of Internet and intranet solutions became mainstream, dependencies on technologies such as web services and Windows Communication Foundation (WCF) were made. Both web services and WCF exposed formal contractual interfaces that exposed the functions contained within them to other programs. As opposed to the previously mentioned DLL API where the module exists on the same computer as the one consuming it, the web service and WCF are hosted on a web server. As a result of being hosted on an Internet or intranet web server, access to the web interface is no longer confined to a single computer and is possible from any device, from any place with an Internet or networked intranet connection.
Recall from the previous chapter where the analysis of the cloud optimized stack took place. From the discussion you learned that in order to be considered cloud optimized, a program must have a small footprint, be able to handle high throughput, and be cross-platform enabled. An ASP.NET Web API is based on the ASP.NET MVC (Model, View, Controller) concept, which aligns directly with the new cloud optimized stack definition. If you have created and/or used web services or WCF in the past, you will see how much simpler and compact an ASP.NET Web API is in comparison. If you have never used either, take my word for it: It is.
In the following Try It Out, you will create an ASP.NET Web API that deals a hand of cards.
Now that the ASP.NET Web API is created, move on to the next section to learn about deployment and then consumption of the Web API.
There are numerous options for deploying your Web App to the Microsoft Azure platform. One of the most popular methods is via a local Git repository or a public Git repository hosted on GitHub. Both the local and public Git repositories provide capabilities for version control, which is a very useful feature. Having version control lets the developer and release manager know what specific changes have been made, when they were made, and by whom. In the event that there are problems or unexpected exceptions when the binaries are compiled or the changes are deployed to the live environment, it is easy to find who to contact about it. Other deployment platforms that can be integrated into Microsoft Azure include Team Foundation Services, CodePlex, and Bitbucket, for example.
There are numerous methods for making deployments of your code to the Microsoft Azure platform. Projects stored in a source code repository versus specific standalone code scenarios each have numerous and individual deployment options.
As the code in the previous Try It Out is a standalone project that is not contained in a version control repository, the deployment is performed directly within the IDE, in this case Visual Studio 2015. Additional methods for deploying a solution not contained in a source code repository include, for example, Web Deploy (msdeploy.exe
) and FTP.
Complete the following Try It Out to deploy an ASP.NET Web API to a Microsoft Azure Web App.
http://handofcards.azurewebsites.net/api/HandOfCards/Benjamin
, where handofcards
is the name you provided when creating the Microsoft Azure Web App and Benjamin
is the name of the player.
By default, different browsers render the results in different ways. For example, Internet Explorer prompts you to download a JSON file, while Chrome displays some XML data. The important aspect is that you get a response. Consuming the API is covered in the next section.
When you publish a Web App from within Visual Studio, it uses Web Deploy in the background to perform the actual deployment. Knowing this, if you have special requirements for the deployment, they can be set within the publish profile located in the PropertiesPublishProfiles
directory. The contents within *.pubxml
contain the configuration items and dependencies for the given deployment.
Once the deployment completes, a browser is rendered to the main page of the Web App (illustrated by Figure 17.6), and not the ASP.NET Web API.
Unlike legacy APIs contained in a .dll
, web service, or WCF service, it is uncommon in practice to access an ASP.NET Web API directly. Rather, in all cases, the call to the API comes from code contained in another (API consuming) project or solution.
Now that the ASP.NET Web API is deployed, it is consumable from any client with capabilities to make an HTTP request and parse a JSON file. The following Try It Out provides all the instructions you need to learn how to consume the just published ASP.NET Web API from an ASP.NET Web Page.
The following Try It Out modifies the Ch16Ex02 ASP.NET Web Site. The primary difference is that instead of retrieving the Cards
from classes contained in the Web Site itself, the Cards
are retrieved from the ASP.NET Web API created and deployed in this chapter.
You will use Visual Studio 2015 to modify the CH16Ex02 example so that it consumes an ASP.NET Web API. The Web API accepts a player's name and returns a hand of cards for that player.
The output of an ASP.NET Web API is a JSON file, the format of which follows a standard format making it easily parsed. The most common means for parsing a JSON file is using the Newtonsoft.Json
libraries.
Newtonsoft.Json
libraries used for parsing the JSON file, right-click on the Solution and select Manage NuGet Packages…, which opens a tab in Visual Studio similar to that shown in Figure 17.7.
Newtonsoft.Json
from the Package list and press the Install button. A Bin
directory is added to the ASP.NET Web Site that contains the Newtonsoft.Json.dll
binary.cshtml
file to the solution by right-clicking on the Ch17Ex02 and selecting Add Add New Item… Empty Page (Razor v3), name it default.cshtml
, and press the Add button.default.cshtml
file here and the one previously created in CH16Ex02 are very similar, but some modifications are required. Consider copying the contents of default.cshtml
from Chapter 16 instead of retyping the entire page.
Newtonsoft.Json
libraries into the Razor file by adding this statement at the very top of the page:@using Newtonsoft.Json;
@{
List<string> cards = new List<string>();
var playerName = Request["PlayerName"];
if (IsPost)
{
string GetURL = "http://handofcards.azurewebsites.net/api/" +
"HandOfCards/" + playerName;
WebClient client = new WebClient();
Stream dataStream = client.OpenRead(GetURL);
StreamReader reader = new StreamReader(dataStream);
var results =
JsonConvert.DeserializeObject<dynamic>(reader.ReadLine());
reader.Close();
foreach (var item in results)
{
cards.Add((string)item.imageLink);
}
}
}
<html>
<head>
<title>BensCards: Deal yourself a hand. </title>
</head>
<body>
@if (IsPost)
{
<label id="labelGoal">Here is your hand of cards.</label>
<br/>
<div>
<p><label id="labelPlayer1">Player1: @playerName</label></p>
@foreach (string card in cards)
{
<img width="75"
height="100"
alt="cardImage"
src=
"https://deckofcards.blob.core.windows.net/carddeck/@card"/>
}
</div>
<label id="errorMessageLabel"/>
}
else
{
<label id="labelGoal">
Enter the players name and deal the cards.
</label>
<br/><br/>
<form method="post">
<div>
<p>Player 1: @Html.TextBox("PlayerName")</p>
<p><input type="submit" value="Deal Hand" class="submit"></p>
</div>
</form>
}
</body>
</html>
When the default.cshtml
page is initially rendered, IsPost
is false
and therefore the calling of the ASP.NET Web API from the C# code contained in the Razor code block does not execute. Instead, only the portion of HTML code within the else
code block gets displayed. The rendered portion contains a TextBox
to capture the player name and a Button
to trigger the posting of the page back to itself.
Once a player name is entered and the Deal Hand button is pressed, the IsPost
property becomes true
and the C# code within the Razor tag at the top of page is executed.
string GetURL = "http://handofcards.azurewebsites.net/api/HandOfCards/" +
playerName;
WebClient client = new WebClient();
Stream dataStream = client.OpenRead(GetURL);
The web address stored in the GetURL
string is the Internet or intranet location of the ASP.NET Web API and is used as a parameter for the OpenRead()
method of the WebClient
class. The WebClient
contains the methods required to perform an HTTP request. The result of the OpenRead()
method is stored in a Stream
object.
StreamReader reader = new StreamReader(dataStream);
var results = JsonConvert.DeserializeObject<dynamic>(reader.ReadLine());
The Stream
object is then passed as a parameter to the StreamReader
constructor. Using the ReadLine()
method of the StreamReader
class as a parameter to deserialize the JSON file using the Newtonsoft.Json
libraries, the results
can then be enumerated through a foreach
statement and added to a List<string>
container named cards
. The cards
list can then be accessed for usage later in the page rendering process.
foreach (var item in results)
{
cards.Add((string)item.imageLink);
}
Review the dynamic
type discussed previously in Chapter 13. It is common practice to use the dynamic
type with JSON files as the structure contained within it is not always castable to a strongly typed class.
Once the parsed results of the JSON file are loaded into the cards
container, the markup code within the IsPost
code block gets executed. The foreach
loop within the Razor tags reads through the cards
container and concatenates the image name with the link to the Microsoft Azure Blob Container created in Chapter 16.
@foreach (string card in cards)
{
<img width="75"
height="100"
alt="cardImage"
src="https://deckofcards.blob.core.windows.net/carddeck/@card"/>
}
You might consider deploying this ASP.NET Web Site to the Microsoft Azure platform using the acquired knowledge from the previous Try It Out. For example, simply right-click the Ch17Ex02 solution, select Publish Web App, and follow the publish wizard. Creating a Web App called "handofcards-consumer
" would then be accessible from http://handofcards-consumer.azurewebsites.net
/. As both the ASP.NET Web API and the Microsoft Azure Blob Container are accessible on the Internet from any place in the world, placing the ASP.NET Web Site on Azure would result in the same outcome (getting a hand of cards).
Over time, if either the consumer or the API become popular and begin receiving many requests, running the Web Apps in FREE mode would likely result in a resource threshold breach that renders the resources unusable. This would not be ideal. In the next section, you learn how to scale an ASP.NET Web API running as a Web App on the Microsoft Azure platform so that users and customers can access your responsive web resource when required.
Scaling to meet the requirements of your users used to be a very tedious, time-consuming, and expensive activity. Historically, when a company wanted to increase server capacity to support more traffic, it required the acquisition, assembly, and configuration of physical hardware into a data center. Then, once the hardware was on the network, it was handed over to the application owners to install and configure the operating system, the required components, and the application source code. The time required to perform such tasks resulted in companies installing a lot of physical capacity to manage peak time usage; however, during times of non-peak usage, the extra capacity simply went unused and sat idle, which is a very expensive and non-optimal way to allocate resources.
A better approach is to use cloud platforms, like Microsoft Azure, that provide the ability to optimally utilize physical resources to scale up, down, and out during the times when the resources are required. When you need physical resources like CPU, disk space or memory, you scale up or out to meet the demands, and when the demand for your cloud-hosted services reduces, you can scale back down and save your financial resources for use with other projects and services.
To successfully complete the exercises in this chapter, you need a Microsoft Azure subscription. If you do not have one, you can sign up for a free trial here: http://azure.microsoft.com
. It is quick and easy to do.
The remainder of this chapter illustrates how to scale an ASP.NET Web API based on CPU demand and during a specific time frame.
handofcards
.” As shown in Figure 17.9, notice that the Web App is in the FREE pricing tier. Auto Scaling is only available when the Web App is in STANDARD mode.
Running a Web App in FREE mode does not get you a whole lot. It is really for testing and learning how the Microsoft Azure platform works. Auto Scaling is only available in STANDARD mode and therefore you must scale to this tier to have access to this feature. Other modes like SHARED and BASIC have the capacity to scale but require a manual configuration to do so.
By default, the Auto Scale settings are to scale up to a maximum of 3 instances of this Web App when the CPU utilization averages between 60% and 80% for a given 60 minute time period examined every 5 minutes.
Notice the INSTANCE SIZE drop down in Figure 17.10. By default, the instance size is Small, which equates to 1 x 2.6 GHZ CPU and 1.75GB of memory. This means that when you scale to three instances, you receive three different virtual machines each with 1 x 2.6GHZ CPU and 1.75GB of memory. Had you set the INSTANCE SIZE to Large, you would instead get three virtual machines with 4 x 2.6GHZ CPUs and 7GB of memory each.
Finally, when the utilization of the CPU or CPUs on the virtual machines running your Web App breaches the lower threshold set as the TARGET CPU value, a new instance or virtual machine is added to your environment up to the maximum number set by the INSTANCE COUNT.
The auto scaling feature is very useful for managing unexpected peaks of usage and requests to your Web App. However, if you already know when your customers or users interact with your Web App, you can plan ahead and have the additional instances available slightly before they are actually needed. The benefit is that instead of a gradual increase or decrease of instances based on CPU usage, you can scale immediately to the number of CPUs and and amount of memory required during only that specific timeframe. For example, if you know that your marketing department is running a campaign during the month of October, you can schedule additional resources to be available during that month. By having the required resources available and warmed up, you can avoid any delay in getting them allocated for use by your users or customers. Perform the steps described in the following Try It Out to see how.
handofcards
". As shown previously in Figure 17.9, notice that the Web App is in the FREE pricing tier. Auto Scaling is only available when the Web App is in STANDARD mode.When you create a schedule for scaling your Web App, a name, start date, start time, end date, and end time are required. With this information, the Microsoft Azure platform manages the number of available instances, which are virtual machines that serve requests to your Web App during the configured time frame. It is possible to create numerous schedules, each having its own number of instances and scale settings. Simply create the schedule, save it, and when it's needed select it from the schedule drop down, and the resources will become available as expected.
17.1 Instead of consuming the ASP.NET Web API from an ASP.NET Web Site application, try consuming it from another program type like a console application or a Windows Universal App.
17.2 What is the maximum size and number of instances you can have for a Web App on the Microsoft Azure platform?
Topic | Key Concepts |
ASP.NET Web API | An ASP.NET Web API is an Internet or intranet interface that exposes methods for consumption from external programs. |
Deploying to the cloud | Use tools like Visual Studio, WebDeploy, Git, or FTP to deploy your program to the cloud. |
Consuming a Web API | An ASP.NET Web API returns the output of the method in a JSON file. Use the Newtonsoft.Json class library to parse and use its content. |
Scaling in the cloud | Microsoft Azure Web Apps let you auto scale based on a defined schedule or CPU usage. Being able to scale up when you need more of a resource and down when it is no longer needed is one of the most valuable benefits of the cloud. |