Deploying ASP.NET MVC 3 Razor Web App to AppHarbor < 4 Minutes

Of all the cloud providers out there, AppHarbor easily provides the smoothest deployment experience for .NET available today. I did this in one shot, including a few mistypes, and still deployed an ASP.NET MVC 3 Web Application to AppHarbor in 3 minutes and 50 seconds.  (Be sure to hit the HD button in the top right corner to get the higher definition video)

 

Also cross posted on Youtube.

Git Rid of Windows Azure and Amazon Web Services (AWS) SDKs with .NET + Git + AppHarbor Deployment Revolution

I’ve been wanting to do a quick write up on the state of cloud apps from my perspective.  What’s my perspective?  Well I’m keeping up with  the SDKs from the big players; AWS and Windows Azure.  I’m also working on several cloud applications and providing consulting for some people and companies when approached related to which stack to go with, how to apply their current stacks (such as Ruby on Rails or .NET) in migrating to a cloud service provider.  Cloud services, or really more accurately utility computing has my personal and professional interest.  Above all, I keep trying to stay informed and know what the best path is for anyone that seeks my advice for moving into hosting & working in the SaaS, PaaS, or IaaS Space.  Feel free to contact me in regards to cloud questions:  adronhall at the famous gmail dot com.  🙂

Now on to the good tidbits that have been released lately.

The latest Microsoft goodies area available.  For the Windows Azure SDK go check out the Microsoft MSDN Site.

For the latest awesome from AWS (Amazon Web Services) SDK check out the AWS .NET Site.

These two SDKs are great for customers who want to build on the bare bones X platform.  Now whatever language & stack one builds in they are tied to that.  Ruby on Rails, .NET, Java, PHP, or whatever.  But getting tied to the stack is kind of like breathing air, one has to live with what air they have.  You can’t exactly get a refund very easily on that.

The Cloud SDKs though for Azure & AWS provide a certain amount of lock in, in addition to the stack lock in you’re using.  One of the easiest ways to prevent this lock in is to use a general deployment method backed by source control on something like Git or Mercurial.  So far though, .NET has been left out the cold.  There has been almost zero support for pushing .NET via Git or Mercurial into a cloud.

Heroku
Heroku

Ruby on Rails however has had support for this since…  well since the idea popped into the minds of the people at Heroku, EngineYard, and the other companies that are pushing this absolutely amazing and powerful technology pairing.

Engine Yard
Engine Yard

Again, for .NET, the problem is it has been left in the dust.  Smoked.  It has left a lot of .NET Developers moving to Ruby on Rails (which isn’t new, this is just one more thing that has pulled more developers away from the .NET stack).

 

Well, that’s changed a bit.  FINALLY someone has gotten the Git + .NET Pairing in the Cloud put together!  FINALLY you can get a cloud application running in a minute or two, instead of the absolutely inane amount of time it takes on Windows Azure (15+ minutes most of the time).  So who has done something about this?

AppHarbor is the first fully deployable solution for the cloud that allows Git + .NET to get going FAST!  I don’t work for these guys at all, so don’t think I’m shilling for them.  I’m just THAT happy that .NET has been pulled out of the dust bins and the community has this option.  I am flippin’ stoked matter of fact.

Currently, because of pricing and ease of deployment, I’ve been solely using AWS.  I can have a .NET MVC app running in AWS in about 5-10 minutes.  Between that speed of setup and the pricing, I pay 2/3 as much as Azure would be and can deploy much fast with a completely traditional .NET deployment.  No special project type needed, no extra configs, just a straight deployment with full control over the server (i.e. I can RDP in with no problem).  Anyway, the list of reasons I went with AWS over Azure really deserve an entire blog entry unto themselves.

AppHarbor
AppHarbor

With AppHarbor though I can step into the realm of doing exactly the same thing a Ruby on Rails Developer would do with Heroku or EngineYard.  Fully PaaS Capable with the scalability and features without needing to port or migrate to an entirely new stack!  I’ll probably keep a number of things running on AWS (such as the pending WordPress Websites I am about to push up to AWS), but will absolutely be starting up some applications to run in AppHarbor.

If you’re a .NET Developer and you’ve been wanting, looking for, and frustrated that the .NET Community didn’t have a Git + Cloud Deployment option for .NET, wait no longer.  Give AppHarbor a look ASAP!

Anyway… off to do a little work on my infrastructure project.  Cheers!

My Current Windows Development Machine Software Stack

I recently did a clean install of Windows 7 64-bit.  It had been a really long time since I listed the current tools, SDKs, and frameworks that I’ve been using.  Thus here’s my entourage of software that I use on a regular basis that is installed on my primary development machines.

Basic Software & System OS

Administration Utilities

Themes & Such

In addition to these packages of software another as important, if not more important to my day-to-day software development includes these software services and cloud hosting services.

SaaS, PaaS, and IaaS

Software I will be adding to the stack within the next few days, weeks, and months.

Exam 70-515 Focus Developing a Web Application by Using ASP.NET MVC 2

…and with this entry, I’ve skipped to the last section of the exam topics related to ASP.NET MVC 2.  Reading and studying the old viewstate based ASP.NET material was a bit rough, which I’ll be writing about in an upcoming entry.  For now, back to focusing on the test at hand.  The MVC Framework is pretty rock star awesome, so with that I’ll get to the notes.

Focus Point:  Developing a Web Application by Using ASP.NET MVC 2

Create Custom Route

  • ASP.NET Routing – ASP.NET enables you to use URLs that do not have a map to specific files in a Web Site.  Because the URL does not have a map to a file, you can use URLs that are descriptive of the user’s action and therefore are more easily understood by users.  Check out URL Patterns for more information (on the same page) and Adding Routes to an MVC Application.  Also for real world implementation you may want to know the difference between Routing and URL Rewriting.
  • Adding Constraints to Routes – In addition to matching the URL request to a route definition by the number of parameters in the URL, you can specify that values in the parameters meet certain constraints.  If a URL contains values that are outside the constraints for a route, that route is not used to handle the request.  You add constraints to make sure that the URL parameters contain values that will work in your application.  Constraints are defined by using regular expressions or by using objects that implement the IRouteConstraint interface. When you add the route definition to the Routes collection, you add constraints by creating a RouteValueDictionary object that contains the verification test. The key in the dictionary identifies the parameter that the constraint applies to. The value in the dictionary can be either a string that represents a regular expression or an object that implements the IRouteConstraint interface. If you provide a string, routing treats the string as a regular expression and checks whether the parameter value is valid by calling the IsMatch method of the Regex class. The regular expression is always treated as case-insensitive. For more information, see .NET Framework Regular Expressions.  If you provide an IRouteConstraint object, ASP.NET routing checks whether the parameter value is valid by calling the Match method of the IRouteConstraint object. The Match method returns a Boolean value that indicates whether the parameter value is valid.
  • Route Class – Provides properties and methods for defining a route and for obtaining information about the route.  The Route class enables you to specify how routing is processed in an ASP.NET application. You create a Route object for each URL pattern that you want to map to a class that can handle requests that correspond to that pattern. You then add the route to the Routes collection. When the application receives a request, ASP.NET routing iterates through the routes in the Routes collection to find the first route that matches the pattern of the URL.  Set the Url property to a URL pattern. The URL pattern consists of segments that come after the application name in an HTTP request. For example, in the URL http:www.contoso.com/products/show/beverages, the pattern applies to products/show/beverages. A pattern with three segments, such as{controller}/{action}/{id}, matches the URL http:www.contoso.com/products/show/beverages. Each segment is delimited by the / character. When a segment is enclosed in braces ( { and } ), the segment is referred to a URL parameter. ASP.NET routing retrieves the value from the request and assigns it to the URL parameter. In the previous example, the URL parameter action is assigned the value show. If the segment is not enclosed in braces, the value is treated as a literal value.  Set the Defaults property to a RouteValueDictionary object that includes values that are used if a parameter is missing from the URL or to set additional values that are not parameterized in the URL. Set the Constraints property to a RouteValueDictionary object that contains values that are either regular expressions orIRouteConstraint objects. These values are used to determine whether a parameter value is valid.
  • Route.Constraints Property – Gets or sets a dictionary of expressions that specify valid values for a URL parameter.  The Constraints property enables you to limit acceptable values for a URL parameter that is processed by a route. You assign a RouteValueDictionary object to the Constraints property. Each element in the RouteValueDictionary object contains the name of a parameter and one of the following:
    • A string that defines a regular expression. The regular expression is case-insensitive.
    • An object that implements the IRouteConstraint interface and that includes a Match method.

The following example is from the MSDN, which shows allowed methods of GET and POST.

[sourcecode language=”csharp”]
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}

public static void RegisterRoutes(RouteCollection routes)
{
string[] allowedMethods = { "GET", "POST" };
HttpMethodConstraint methodConstraints = new HttpMethodConstraint(allowedMethods);

Route reportRoute = new Route("{locale}/{year}", new ReportRouteHandler());
reportRoute.Constraints = new RouteValueDictionary { { "httpMethod", methodConstraints } };

routes.Add(reportRoute);
}
[/sourcecode]

Create Controllers and Actions

  • Controller and Action Methods in MVC Applications – The ASP.NET MVC Framework maps URLs to classes that are referred to as controllers.  Controllers process incoming requests, handle user input and interactions, and execute appropriate application logic.  A controller class typically calls a separate view component to generate the HTML markup for the request.  The base class for all controllers is the ControllerBase class, which provides general MVC handling.
  • Two great articles;  MSDN Magazine titled Building Web Apps without Web Forms and there is the What’s New section on the ASP.NET MVC Site.
  • Create an action – You add a new action to a controller by adding a new method to the controller. These methods must meet these requirements:
    • Must be public
    • Cannot contain a static method
    • Cannot be an extension method
    • Cannot be a constructor, getter, or setter
    • Cannot have open generic types
    • Cannot contain out or ref parameters
    • is not a method of the controller base class.
  • Create a Controller – This tutorial covers creating a controller including the menu options and scaffolding, etc.
  • Action Filtering in MVC Applications – In ASP.NET MVC, controllers define action methods that usually have a one-to-one relationship with possible user interactions, such as clicking a link or submitting a form.  For example, when a user clicks a link, a request is routed to the designated controller, and the corresponding action method is called.  ASP.NET MVC provides action filters that are custom attributes that provide a declarative means to add pre-action and post-action behavior to controller action methods.

MVC 2 Template Project

Structure an ASP.NET MVC Application

  • MVC Framework and Application Structure – In an ASP.NET website, URLs typically map to files that are stored on disk (usually .aspx files).  These .aspx files include markup and code that is processed in order to respond to the request. The ASP.NET MVC framework maps URLs to server code differently than an ASP.NET Web Forms page. Instead of mapping URLs to ASP.NET pages or handlers, the framework maps URLs to controller classes. Controller classes handle incoming requests, such as user input and interactions, and execute appropriate application and data logic, based on user input. A controller class typically calls a separate view component that generates HTML output as the response. The ASP.NET MVC framework separates the model, view, and controller components.
  • Global URL Routing Defaults see below (from MSDN Article)

[sourcecode language=”csharp”]
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);

}

protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
}
[/sourcecode]

Create and Customize Views

Using the begin BeginForm Helper

[sourcecode language=”html”]
<% using(Html.BeginForm("HandleForm", "Home")) %>
<% { %>
<!– Form content goes here –>
<% } %>
[/sourcecode]

Using it declaratively…

[sourcecode language=”html”]
<% Html.BeginForm(); %>
<!– Form content goes here –>
<% Html.EndForm(); %>
[/sourcecode]

Using the Checkbox Helper

[sourcecode language=”html”]
<%= Html.CheckBox("bookType") %>
[/sourcecode]

Using the DropDownList Helper

[sourcecode language=”html”]
<%= Html.DropDownList("pets") %>
[/sourcecode]

[sourcecode language=”csharp”]
List<string> petList = new List<string>();
petList.Add("Dog");
petList.Add("Cat");
petList.Add("Hamster");
petList.Add("Parrot");
petList.Add("Gold fish");
petList.Add("Mountain lion");
petList.Add("Elephant");

ViewData["Pets"] = new SelectList(petList);
[/sourcecode]

Using the RadioButton Helper

[sourcecode language=”html”]
Select your favorite color:<br />
<%= Html.RadioButton("favColor", "Blue", true) %> Blue <br />
<%= Html.RadioButton("favColor", "Purple", false)%> Purple <br />
<%= Html.RadioButton("favColor", "Red", false)%> Red <br />
<%= Html.RadioButton("favColor", "Orange", false)%> Orange <br />
<%= Html.RadioButton("favColor", "Yellow", false)%> Yellow <br />
<%= Html.RadioButton("favColor", "Brown", false)%> Brown <br />
<%= Html.RadioButton("favColor", "Green", false)%> Green
[/sourcecode]

Using the Textbox Helper

[sourcecode language=”html”]
Enter your name: <%= Html.TextBox("name") %>
[/sourcecode]

Exam 70-515 Pt 1 Focus on Developing Web Forms Pages

I’m going to be taking the Web Application Development with Microsoft .NET Framework 4 in the very near future.  Since I’m going to be scribbling a few notes and studying up, it seemed like I’d publish my studies.  With that, here is round 1.  My intent is to study each focus area and make a blog post about it.  Beware, these could be some rather messy blog entries, I’ll try to keep them somewhat cohesive though. (Note, the base of these notes are from the actual 70-515 curriculum and also Niall Merrigan’s Blog Entry “MCTS Web Applications .NET 4 – 70-515 – Objectives List Part 1” helped a lot!  I’ve of course added my extra 2 cents to most of these.  Cheers!)

Focus Point:  Developing Web Forms Pages

Configure Web Forms Pages

A page directive is a page-specific attribute used by the ASP.NET page parser and compiler.  Some of these attributes I’ve linked and detailed below:

  • Page.AsyncMode Property – Sets a value indicating the page is processed synchronously or asynchronously.  The AsyncMode property is set by the Page parser when code for the page is generated. Use the Async attribute in @ Page directive to set this value.  Asynchronous pages do not work when the AspCompat attribute is set to true or the Transaction attribute is set to a value other than Disabled in the @ Page directive.
  • Page.AsyncTimeout Property – Gets or sets a value indicating the time-out interval used when processing asynchronous tasks.  The asynchronous time-out of the page represents the amount of time that the page will wait to perform asynchronous tasks. In most circumstances, do not set this property in code. Set the page asynchronous time-out interval using the pages element of the Web configuration file or in the @ Page directive. Values set in the page configuration section are overwritten by the page directive.  Define your asynchronous task using the PageAsyncTask class and register a beginning, an ending, and a time-out handler. If the asynchronous task does not complete in the time interval specified, the time-out handler will be invoked.
  • Page.AspCompatMode Property – Sets a value indicating whether the page can be executed on a single-threaded apartment (STA) thread.  This allows the page to call STA components, such as components developed with Visual Basic 6.0. Setting this property to true also allows the page to call COM+ components that require access to the unmanaged ASP built-in objects. These are accessible through the ASP ObjectContext object or the OnStartPage method.  In most circumstances, do not set this property in code. Set the aspcompat attribute to true using the @ Page directive in the .aspx file. When the page is requested, the dynamically generated class sets the property.
  • Page.Buffer Property – Sets a value indicating whether the page output is buffered.  In most circumstances, do not set this property in code. Set the Buffer attribute to true using the @ Page directive in the .aspx file. When the page is requested, the dynamically generated class sets the property.
  • Control.ClientIDMode Property – Gets or sets the algorithm that is used to generate the value of the ClientID property.  The values are AutoID which generates the value by concatenating the ID values of each parent naming container with the ID value of the control, seperated by an underscore character.  The Static value sets the value statically and makes the control the top of the hierarchy of naming containers if it is a container.  Predictable algorithm is used for controls that are data-bound controls and concatenates the ClientID value of the parent with the ID value of the control.  Inherit sets it to the parent control.
  • Page.ClientTarget Property – Gets or sets a value that allows you to override automatic detection of browser capabilities and to specify how a page is rendered for particular browser clients.  If you do not set the ClientTarget property, the HttpBrowserCapabilities object associated with the Page.Request property reflects the browser capabilities associated with the value (alias) that you provide.  uplevel, which specifies
  • CompilationMode Enumeration – Defines constants that specify how ASP.NET should compile .aspx pages and .ascx controls.  Members include; Auto sets ASP.NET to not compile the page if possible, Never states the page will not be dynamically compiled, and Always sets ASP.NET to compile every time.
  • Control.EnableViewState Property – This one has been the disdain of many serious web developers, as the view state becomes a horrifying beast to deal with.  But I digress, it may appear on the test so know about it.  🙂  This property gets or sets a value indicating whether the server control persists its view state, and the view state of any child controls it contains, to the requesting client.
  • Page.EnableViewStateMac Property – Gets or sets a value indicating whether ASP.NET should check message authentication codes (MAC) in the page’s view state when the page is posted back from the client.
  • Page.ErrorPage Property – Gets or sets the error page to which the requesting browser is redirected in the event of an unhandled page exception.
  • Page.MasterPageFile Property – Gets or sets the file name of the master page.
  • Page.MetaDescription – Gets or sets the content of the “description” meta element.
  • Page.MetaKeywords – Gets or set the content of the “keywords” meta element.
  • Page.Theme Property – Gets or sets the name of the page theme.
  • ViewStateEncryptionMode Enumberation – Specifies whether view-state information is encrypted;  Auto sets the encryption by calling the RegisterRequiresViewStateEncryption method, Always sets it to encrypt always and Never does not encrypt even if the control requests it.
  • Control.ViewState Property – Gets or sets the view-state mode of this control.
  • Control.ViewStateMode Property – Gets or sets the view-state mode of this control.
  • Compiler.WarningLevel Property – Gets the compiler warning level.
  • Saving and reading values in View State:  Save Values / Read Values
  • Auto Event Wire Up – i.e. ASP.NET Web Server Control Event Model.
  • PageSection.EnableEventValidation Property – Gets or sets a value that specifies whether event validation is enabled.
  • General configuration settings (ASP.NET) – This topic covers web.config files and setting up configuration sections within this file.  Some of the topics to be familiar with include; connectionStringssystem.web, configSections, appSettings, location, System.Configuation, and System.Web.Configuration.
  • XHTML Standards in Visual Studio and ASP.NET
  • Editing ASP.NET Configuration Files – Case-sensitivity, custom sections, remote configuration files, etc.
  • Making controls easier to access via JavaScript since they’re often cryptic…  Walkthrough:  Making Controls Located in Web User Controls Easier to Access from JavaScript, How to:  Access Controls from JavaScript by ID, and Walklthrough:  Making Data-Bound Controls Easier to Access from JavaScript.

Implement Master Pages and Themes

Implement Globalization

Handle Page Life Cycle Events

Implement Caching

There are a few more topics for this section of the test, I’ll follow up with the remainder of those notes, and move on to the next topic section.  Enjoy…