WROX.COM CODE DOWNLOADS FOR THIS CHAPTER
You need to download the MovieFu.zip file.
While the goal of this book centers primarily on deploying and maintaining websites in Windows Azure, it would be hard to get a full picture of the process and its nuances without a concrete example from which to work. You can read all you want to about how to ride a horse, but it's a whole different story when you finally get on the saddle! For that reason, you're about to saddle up and walk through the deployment and configuration of an actual reference application. This will enable you to learn about the various aspects of the deployment process as well as manage your deployments once they are out in the cloud.
So here's the premise: Imagine you have a great collection of movies that you want to track and share with your friends. You even want to give them a chance to comment on the movies and rate them, which is great information to have if you decide to host a movie night. You set up a website that enables you to create your library of flicks, search for movies, and keep track of the directors that make your favorite films. You call the site MovieFu and build the application using the ASP.NET MVC Framework.
Again, this book — and even this chapter — is not about teaching you how to build websites on ASP.NET or helping you learn the MVC Framework. There are many good references out there for that. This project is not the pinnacle of code quality, it's not the best-looking date at the UI design ball, nor is it meant to represent best practices, but it does illustrate the kinds of things you may be doing when you publish to WAWS.
The first thing you need to do is get the code for the app so that you can start exploring it. If you have met the requirements described in the What You Need to Use This Book section of the Introduction, it is ready to go and will run for you out of the box.
You can find the code for this chapter at Wrox.com. The instructions for locating the code and downloading it are located in the Introduction to this book. The code itself is in a zip file. Once downloaded, right-click on the file in File Explorer and select the Properties option in the context menu. In the Properties dialog, on the General tab, there is a section labeled Security. For files that have been downloaded from the Internet, this section includes an Unblock button. If you see this button, click it, and then click OK. This is not a requirement, but it eliminates some annoying warning messages when you open the project in Visual Studio.
Now that you have the code in a zip file, extract it (by right-clicking on the file and selecting Extract All, or using any other method of your choosing) to a directory.
Take a few minutes to launch the application and ensure that your machine is correctly configured and that you have all the files you need to get started:
NOTE If you have multiple versions of Visual Studio installed on your machine you may be prompted to select the version in which to load the solution. If you're presented with this choice, be sure to pick Visual Studio 2012 to take advantage of the features related to publishing your application to Windows Azure.
That's it! You can close the browser window at this point and return to Visual Studio. You'll examine the application later in this chapter, but first you're going to look at the bits that make the website tick.
There aren't too many surprises in MovieFu, and you can expect to find most of the resources where they would be in any MVC 4 application. The website was created as an ASP.NET MVC 4 Web Application project, using the Empty Application template. The Twitter.Bootstrap.Mvc4 open-source library adds some style to the website and gives you tools, such as automatic scaffolding of standard CRUD views.
You should familiarize yourself with the following major elements to become comfortable working with the application:
Those of you who are experienced in ASP.NET know that you're not locked into any specific database platform. This is one of the best things about using a mature framework; you have not only the freedom to choose which database back end to leverage, but also the flexibility to do so when required. It can be very frustrating to work inside a technology stack that demands specific requirements and doesn't easily allow you to satisfy your project's functional requirements. This is especially true in integration projects or extensions to legacy systems when you aren't given the option to elect which back end you'll be building from or adding to. Whether it is MS SQL, Oracle, MySQL, or a no-SQL solution that you'll be using to maintain your application's data, ASP.NET likely has the providers for you to connect and manipulate data. As a greenfield project, MovieFu is not bound by many constraints and could have used any number of solutions.
That said, the tools that Microsoft provides to developers are typically aligned with the technology stack for which they are actively developing and providing guidance. Visual Studio has some great tooling and support for MVC and Entity Framework acting in unison, and Entity Framework is currently the data access technology that is recommended by Microsoft for anyone starting a new project. For these reasons, MovieFu was built to dynamically generate the database using Entity Framework Code First.
NOTE Entity Framework is an object-relational mapper (ORM) that handles most of the details related to connecting to the database as well as managing entity state and persistence. Entity Framework enables you to define the model in a number of ways. A common approach for applications for which there is already a database involves using the database schema to generate the initial model. Customizations can be executed afterwards, but the entities tend to be very close to the database table structure.
A second approach that recent versions of Entity Framework support is known as Code First. You start by creating a number of different classes, each with its own collection of properties. Then a database schema can be generated based on the properties in each class.
The default templates for many web projects in Visual Studio 2012 now include Entity Framework by default — which you can verify in the Packages.Config file in the root of your project — but you can also add it to any application or library by installing it through the Package Manager Console, shown in Figure 8-2.
Alternatively, you can add Entity Framework through the Manage NuGet Packages dialog, shown in Figure 8-3.
As a block of code, Entity Framework is two important things. First, it's an open-source project that anyone is free to contribute to and work with. This means you can go to the project website, clone the source code, make changes, and then submit pull requests. Second, it's a versioned, signed library that is considered a supported product by Microsoft, which means you are allowed to use it in your projects as you would any other code provided by Microsoft, released under the Apache License 2.0.
As a library that you will use in your application, Entity Framework allows you to work with default settings to connect to a database and provides you with extra tools to manage entities. It includes Visual Studio designers that enable you to work with existing databases or start from scratch, and beginning with version 4.3 it is possible to use plain old CLR objects (POCOs) to lay out your data model with the support of migrations. This is the Code First strategy described earlier.
Thanks to Code First, you can start by writing a simple POCO to represent your entity, such as the Movie class in Listing 8-1, just as you would in any other project.
LISTING 8-1
public class Movie { public int MovieId { get; set; } public string Title { get; set; } public string Description { get; set; } public string ImageUrl { get; set; } }
This model is just a class with primitive types as properties to describe a movie that you will store in the application. However, this class serves as a base that you can augment, decorate, and effectively define advanced schema attributes for what will become a table in a database and how the model will be validated. Listing 8-2 starts to illustrate how a POCO can incorporate some of those features, including marking fields as required. In the case of ReleaseYear, the Range attribute provides framework-level validation instructions that can be used from JavaScript libraries or in your controller. Virtual members enable you to create references to other tables and more easily access related data, using a pattern known as Lazy Loading; these members are also known as Navigation Properties.
LISTING 8-2
public class Movie { public Movie() { this.ReleaseYear = DateTime.Now.Year; this.Ratings = new HashSet<Rating>(); } public int Id { get; set; } [Required] public string Title { get; set; } [Required] public string Description { get; set; } [Range(1877,2020)] public int ReleaseYear { get; set; } public virtual int DirectorId { get; set; } public virtual Person Director { get; set; } public ICollection<Rating> Ratings { get; set; } }
By itself, the Movie class is nothing more than a blueprint of an object that you can instantiate, but when you add the DbContext in Listing 8-3 to your application, you can start to think of that movie as a row in a database.
LISTING 8-3
public class MovieFuContext :DbContext { public DbSet<Movie> Movies { get; set; } }
When you create an instance of a MovieFuContext object, Entity Framework uses a series of conventions to attempt to make a database connection. Failing this connection through a series of strategies, Code First kicks in, using a default configuration to create the database on your behalf and subsequently issuing the commands required to create your tables. At this point, it is impossible to provide specific details regarding what these defaults will be for you, as it depends on the version mix of Entity Framework and Visual Studio that you are using; however, looking in web.config will tell you how Entity Framework wired itself up, as shown in Listing 8-4 from the web.config in MovieFu. In this case, the sample application was created with Visual Studio 2012, and Entity Framework 5.0 is using Local Db.
LISTING 8-4
<defaultConnectionFactory type=“System.Data.Entity.Infrastructure .LocalDbConnectionFactory, EntityFramework”> <parameters> <parameter value=“v11.0” /> </parameters> </defaultConnectionFactory>
At this point, you have created a solid solution: low overhead to create tables and the database itself; default conventions for accessing the database; and the capability to override the defaults to meet your needs. But what happens when you need to add fields to a table, or add new tables? This is where migrations enter the picture, enabling you to control how changes are applied in the database, modify existing table structures, and seed data — and because these actions are all expressed through code, you can do some crafty things and handle these processes differently depending on where the code is executing.
While migrations are enabled in the solution you're working through, they are not enabled by default. If you need to enable them in a project, follow these steps:
This will create a Configuration.cs file in your application with a class called Configuration that inherits from a generic class named DbMigrationsConfiguration. The inheritance specifies the DbContext that you have in your project, and a constructor is created for you by default that disables automatic migrations (this is a good thing!). Only one (useful) override is available: Seed, which enables you to manipulate the database anytime a migration is applied. Listing 8-5, the Configuration class for MovieFu, demonstrates one way to ensure that a base set of data is available in your application through the AddOrUpdate method. AddOrUpdate works by specifying how you want to identify a seed value — MovieFu uses the name of Theme — and what value you want to either ensure is in there or adjust. While Theme is a fairly simple object, imagine more complex objects whose required initial values change throughout a project's development.
LISTING 8-5
internal sealed class Configuration : DbMigrationsConfiguration<MovieFu.Models .MovieFuContext> { public Configuration() { AutomaticMigrationsEnabled = false; } protected override void Seed(MovieFu.Models.MovieFuContext context) { context.Themes.AddOrUpdate(t => t.Name, new Theme { Name = “Favorite Superhero” }, new Theme { Name = “Retro 80's” }, new Theme { Name = “Disco Nights” }, new Theme { Name = “Wild, Wild West” }, new Theme { Name = “Favorite Character From the Movie” }, new Theme { Name = “Famous Dead People” }, new Theme { Name = “PJ Party” }, new Theme { Name = “Boring old Plain Clothes” } ); } }
NOTE Automatic migrations are a groovy but not always practical addition to your toolbox. They enable you to easily update the database without having code files that provide explicit instructions on how to do it. Unfortunately, the luxury is not without its costs: You can't “downgrade” your database, you don't get named versions of your database, and there are a number of things they can't do for you, such as properly rename columns; therefore, they should only be used in experimental scenarios. I don't recommend using them in any code that is destined for a production environment, but they can be a great way to explore Entity Framework.
With migrations enabled, you can now start to look at the code that drives the changes. Each migration is a class that inherits from DbMigration, giving you a rich set of operations to perform on the database. To see a complete list, visit http://msdn.microsoft.com/en-us/library/system.data.entity.migrations.dbmigration(v=vs.103).aspx.
Migrations can be as simple as renaming a field. For example, consider the code in Listing 8-6, which renames the MovieTitle column to Title in a table called Movies.
LISTING 8-6
public class SampleMigration : DbMigration { public override void Up() { RenameColumn(“dbo.Movies”, “MovieTitle”, “Title”); } }
The Up() method is abstract in the base class and thus the only member that you need to implement. There is also a virtual method called Down(), illustrated in Listing 8-7, that you can elect to override, which enables you to change the name of the column back to its original name.
Why might you want to do this? When you ask Entity Framework to move your database to a specific version, all the explicit migrations from the current version to the target version are discovered in your project through reflection and then executed. If you are moving to a higher version, the Up() method is called on each migration in order until the target version is reached. Likewise, if you are moving to a lower version, the Down() method is called, if it exists, until Entity Framework lands on the version you requested. In addition, if you follow the practice of tying your product releases to a database version, you'll have code that targets a different data structure, which is precisely why you should implement the Down method in your migrations. When you start the app after a downward migration and the code executes, it will try to create classes, invoke actions, and render views; and it will expect entities to be consistent with the version in question.
After you have enabled migrations, you need to create one anytime a field or table change is required. Thankfully, there is a whole set of tooling to help build this out on your behalf.
You create a migration by returning to the Package Manager Console and executing the Add-Migration command, passing the name of your migration as a parameter:
Add-Migration Your-Migration-Name.
As a best practice, give the migration a meaningful name that lets other developers (and you, in the future) know what purpose it serves. The example in Listing 8-8 shows the migration I created when adding an ImageUrl property to the Movie class.
LISTING 8-8
public partial class movieimage : DbMigration { public override void Up() { AddColumn(“dbo.Movies”, “ImageUrl”, c => c.String()); } public override void Down() { DropColumn(“dbo.Movies”, “ImageUrl”); } }
All the migrations, as well as the configuration class, are located in the Migrations folder in the root of your project. This is a convention that is followed by the tooling in Entity Framework, and each new generated class will appear in the same directory.
The last thing you'll need to know is how Entity Framework is signaled from MovieFu in order to start migrations. MovieFu employs a very basic strategy for the purpose of this book: Migrate to the latest version of the database when the application is launched. You will find the following line of code in Global.asax.cs:
Database.SetInitializer( new MigrateDatabaseToLatestVersion<MovieFu.Models.MovieFuContext, Migrations.Configuration>() );
This tells Entity Framework to move to the latest version of the MovieFuContext using the configuration from the specified class.
You had a quick look at the site earlier in the chapter, but now it is time to explore some of the available functionality more deeply. The site requires a little bit of data entry to be somewhat useful, and you'll need to be signed in to do any data editing.
The People and Movies links resolve to actions on controllers that are protected by an Authorize attribute. If you try to access them you'll be redirected to a login page where you can use existing credentials or click through to the Register page, which is shown in Figure 8-4.
When you deploy the site none of the users you create will move to the cloud with the site. Because you're using Code First and EF, a new database will be created in Winodws Azure SQL Database as the code is executed on the live site.
You can access the create screens for both Movies and People from the website's menu at the top of the screen. Movies have a Director property that needs to be set by selecting someone from the People table, as shown in Figure 8-5.
To help facilitate this, a few features have been put in place to kick-start the data entry process. First, the open-source library AngelaSmith is used in the Seed method of the migrations Configuration class to generate a random list of 15 people. Next, the same method does a quick count of the movies in the database, and if none are present it proceeds to populate it with a few titles.
With a few movies in place you can now start telling your friends about the site and inviting them to sign up, sign in, and start rating your library. The form to add a rating is shown in Figure 8-6 and can be located on the Details view of any movie on the site.
As folks add movie ratings, they will appear on the movie's detail page above the rating form.
It's time for the big show! You're ready to push that site out into the wild and bring it to life, and you have the instructions from this book to guide you. If you would like to take a stab at it on your own, here are the steps you need to do to get it live:
The following sections provide the complete instructions.
For explanations and screenshots along the way, you can review Chapters 1 and 2, which go into greater detail. To follow along more quickly if you're comfortable with the process, log into the Management Portal and navigate to the Web Sites listing, then follow these steps:
Chapters 2 and 4 cover various aspects of publishing and configuring the site, including downloading profiles and incorporating your Azure settings into your tools. To follow along here, make sure you have the solution opened in Visual Studio 2012, and then perform these steps:
Visual Studio 2012 will compile the list of files that need to move to the cloud, create a deployment script, and push everything you need up to your website. Your browser will open and in a few moments your site will be displayed.
You can override the settings of the application in a number of different ways as illustrated in Chapters 4 and 7. Here, you'll use the Management Portal to override the name of the application that is displayed in the website's menu:
As soon as the portal is done saving the configuration of your site, you can press the Browse button on the command bar to see the changes. Your application name will be updated in the menu.
You've been skinning cats all different kinds of ways throughout the book, so why not try your hand at some additional exercises that will help develop your skills?
Most folks feel better equipped to learn a new technology when they can start to work from a place they are already familiar with. Throughout this chapter you explored an ASP.NET MVC website that demonstrates qualities of applications you may already be working on and will be able to adapt to cloud deployment.
You examined the key components of the application and considered aspects such as membership, authorization, and database migrations. With MovieFu, a working application with a lot of room to grow, you can continue to learn, push, poke, prod, and extend an application that runs in the cloud. Congrats!