AppHarbor + ASP.NET MVC + Orchard = Awesome

ASP.NET development has come a long way.  It’s now easier to practice Test Driven Development (TDD) thanks to ASP.NET MVC and all the open source tools out there from Ninject to Moq to Entity Framework Code First.  But one thing remains real sucky in the .net world and that is deployment.  Have you tried deploying an Azure application?  It sucks and I hate Azure for it.  I created a web service using Python and deployed it on Google AppEngine and it was much faster to create, easier to maintain and deploy even though I knew zero Python.  Deploying a site to IIS is a pain in the butt.

I have always been envious of how easy it was/is to deploy a rails app.  It takes seconds and usually one command line.  It is just awesome.  So, I was really excited when a few weeks ago I ran across AppHarbor and it looked too good to be true.  I thought I would see how easy it would be to create a site and deploy it.  Instead of creating an app from scratch though, I am going to create an Orchard website.  If you haven’t seen Orchard, go check it out.  It’s really cool.  It’s a CMS/Blog engine written in ASP.NET MVC and is open source and very extensible.

Prerequisites: Setup git on your computer, see this link for instructions.

So, here is how to get a website up and running in seconds…

1 – Login to AppHarbor and create a new application

2011-05-03_1545

2 – Change your new application settings to enable write-access to the file system

2011-05-03_1607

3 – Start WebMatrix and create a new site from Web Gallery

2011-05-03_1548

4 – Choose Orchard and name your website

2011-05-03_1550

5 – Open up a command prompt (I use Console2)

6 – Change to the path of your new website e.g. cd c:\websites\mywebsite

7 – run the following commands

  • git init
  • git add .
  • git commit –m “initial commit”
  • git remote add appharbor https://eibrahim@appharbor.com/MyWebsite.git (the URL will be unique to your app)
  • git push appharbor master (enter your AppHarbor password)

8 – Visit your new site on appharbor, in this example the site is located at http://mywebsite.apphb.com/ 

9 – DONE!!!  Just follow the prompts to setup Orchard

 

You have just deployed a web app and have it hosted for free.  You can easily scale it using AppHarbor’s cloud infrastructure.  It is simply awesome. 

Another cool feature is that every time you want to deploy a new version, you simply commit your changes and run the git push command above.  AppHarbor maintains different versions of your app and you can easily switch between versions.  So if you deployed a bad version, you simply click a link and deploy the last working version.

2011-05-03_1941

I personally haven’t deployed a scalable app on AppHarbor, so I would love to hear your feedback on how well the scaling works and if it is cost-effective or not.

“I Quit” 1 Year Anniversary

It has been a year since I quit my job and decided to go independent.  I didn’t know what I was going to do, the economic outlook wasn’t good, I had two rental properties and a condo that I didn’t know how I was going to pay for.  I was armed with only hope, ambition, credit cards and my fiancé’s love & support.
The first three months, I toyed around with different and random ideas, I read lots of technical books and online material.  I learned a ton of stuff and in the process I launched an open source project called Yonkly that was written using Microsoft’s newest web framework – asp.net mvc.
Yonkly was initially a Twitter clone, it was free and it was open source.  Feedback was positive for the most part and I kept getting requests for customization and installation.  One of my first clients was isweat.com which was a custom version of Yonkly.  This was a good deal because I was getting paid to add more features to Yonkly as well as have a good reference client.  I was also lucky to have a great client Ryan Lee – who is just an all around great guy and pays on time – actually ahead of time.
I kept getting more praises on Yonkly and more requests for customization.  That’s when I thought to myself that there seem to be a market for this things.  It looks like people want to create their own Twitter-like website for whatever reason.  Some wanted to cultivate a community around a niche topic, some wanted to generate money with ads, some wanted to communicate/collaborate within a group/team/company.  Regardless of the reason, there seemed to be enough demand to take this to the next level.
I was confused (and still am) on which direction to go.  There was the WordPress direction – offer a free, open source, extensible platform à la wordpress.org with an accompanying free hosted version à la wordpress.com.  There was the Ning direction – offer a hosted, subscription-based product à la Ning that lets anyone create their own microblog with zero-friction.  I kept going back and forth and finally settled on a hybrid model that leans more to the ning model.  I still kept the open source version out there (albeit it is outdated).  I chose a subscription-based model because I was tired of all these eyeball-centered business models with ads as their only revenue.  I wanted to create a sustainable business that will generate predictable recurring revenue.  The result was the birth of the hosted version of Yonkly – currently at yonkly.com.
Similar to ning, Yonkly allows you to easily create a microblog by simply selecting a name and a url.  You can create soccermoms.yonkly.com and voila, you got yourself a Twitter-like website focused around soccer moms.  If this is a small community then you can set it up for free.  My first release had 3 plans priced at 25, 50 and 100, I quickly realized that these were ridiculously high prices.  I also realized that people like, no LOVE free stuff.  I quickly adapted by introducing a free plan and changing the prices to 5, 15 and 25 with even reduced prices for annual subscriptions.
The cool thing about Yonkly is its approach to white-labeling.  If you are a premium subscriber, you can create a site with your own domain, your own look and feel and with no mention of Yonkly anywhere.  Good examples of that is isweat.com and blogpei.com.  Yonkly has come a long way and now has thousands of users and over 1600 networks hosted on it.  It is also profitable.  I know that is hard to believe in this day and age.  I am not rich off Yonkly (yet) and it won’t pay my mortgage BUT it pays for itself and then some.  I have some really big plans for Yonkly which I will discuss in a future post.
So that was the story of Yonkly thus far; about 3  or 4 months after I quit my job, I accidently :) signed a book deal with Wiley Wrox on ASP.NET MVC and Test Driven Development (TDD).  It has always been a dream of mine to write a book, so I was really excited.  I won’t get rich of the book but I think it is an excellent learning experience and a great résumé filler.  It forced me to get better about the book’s subject and to get better at writing in general.  It also made me appreciate the amount of work that goes into each book.
I thought it was going to be an easy task, I mean, all I have to do is write.  Right?  Wrong, that was so far from the truth.  I was cranking out an average of 3 pages a day – a mind numbingly slow rate.  It wasn’t consistent either.  Sometimes, I will write 15 pages in 3 hours and then spend 2 weeks writing the next 15.  Sometimes I also feel that I can talk about a specific topic for 20 pages and then 2 paragraphs in, I realize that I got nothing else to say.  It has been an interesting experience.  The good news is that I am pretty much done with the book now and it should be published by May.
In conclusion, a year after I quit my job here are the end results:
Bad:
  • Huge credit card debt
  • Possibility of foreclosure on rental properties
  • Zero financial security
  • No stable income
  • Unpredictable outcome
Good:
  • Yonkly launched – officially my first web 2.0 service built from scratch
  • Wrote a book – to be published soon by Wiley Wrox
  • Proposed to my girlfriend (Laura) – she said yes
  • Adopted a puppy.  His name is Mac, we also considered naming him Dot com, Google, C# and Web.

001e089e-eac8-441a-a30c-c7c817aa016b

Overall, I am glad I quit my job.  Other than the fact that I am broke, I learned and accomplished a lot and ready to take Yonkly to the next level.
You can follow me on twitter at twitter.com/eibrahim for more updates and to track the progress of Yonkly, check out the blog at blog.yonkly.com or follow it at twitter.com/yonkly.

Client & Server Side Validation in ASP.NET MVC

[Update: The code is open-sourced at http://code.google.com/p/mvcvalidation/]

The asp.net mvc codeplex preview 5 version just came out a few days ago and it includes a lot nice enhancements.  For the best introduction read Scott’s post

Some of my favorite changes happened in validation.  Incidentally, I was already working on a post to talk about doing client and server side validation the easy way.  The inspiration came after reading Steve Sanderson’s post and watching his screencast on how he created a model-based client-side validation – very cool.

I want a simple way to perform client and server side validation for the application I am creating for my book and my objectives are simple (yet there is no easy way to do it):

  1. Have a model-based validation mechanism
  2. Have the least amount of repetition (DRY)
  3. Client side validation using jQuery
  4. Server side validation

First, I will show you how it works then I will explain how I got there.  Here is my model class for a user

   1: public class User
   2: {
   3:     public virtual string UserName { get; set; }
   4:     public virtual string Email { get; set; }
   5:     public virtual string Password { get; set; }
   6:     public virtual Guid ProviderId { get; set; }
   7: }

To add validation to it, I simply decorate it with the appropriate validation attributes.  It ends up looking like this:

public class User
{
    [ValidateNonEmpty("Username is required")]
    public virtual string UserName { get; set; }

    [ValidateNonEmpty("Email is required")]
    [ValidateEmail("Invalid email address")]
    public virtual string Email { get; set; }

    [ValidateNonEmpty("Password is required")]
    [ValidateLength(4,50,"Password should be at least 4 characters long")]
    public virtual string Password { get; set; }

    public virtual Guid ProviderId { get; set; }
}

I then generate the client script by adding 1 line of code to my view

<%=Html.ClientSideValidation("formCreateList", ViewData.Model) %>

On the server side, I simply make a call to a validation method from my controller

[Authorize]
[AcceptVerbs("POST"), ActionName("Create")]
public ActionResult Save(User newUser)
{
    AppHelper.ValidateModel(ViewData.ModelState, newUser);
    //the rest of the action code
}

If there are any validation errors on the server, I display the errors by using the framework helper method ValidationSummary.  All I have to do is add this 1 line to the view

<%=Html.ValidationSummary() %>

JavaScript

That’s all there is to it.  Now let’s talk about how it works.  The first challenge was generating the JavaScript to validate on the client. 

I decided to use the excellent jQuery Validation plugin.  The plugin gives me 2 ways to validate my form.  The first method uses classes on the the fields to be validated, for example a required email field would look like this

<input id="email" name="email" size="25"  class="required email" />

The second method uses rules that are defined in JavaScript and look like this

<script type="text/javascript"> 
$("#signupForm").validate({
        rules: {
            email: {
                required: true,
                email: true
            }
        },
        messages: {
            email: "Please enter a valid email address"
        }
    });
</script>

Check out the plugin documenation and demos to understand how it all works.

Since I was generating the script on the server and I wanted to make only one call, I went with the second option.

The script generator simply loops through all the model properties and their attributes and generate the appropriate script.  Afterthought: Now that I think about it, I could have easily generated a script to add classes to the elements using jQuery’s addClass method…  Oh well, maybe someone else will be kind enough to do it.

Castle Validator

I used the Castle Validator Component as my validation framework.  That’s where all the validation attributes you see above come from, but you can also create your own validators.  I then created a class called JQueryValidationProvider that implements IBrowserValidationGenerator interface in the Castle.Components.Validator namespace.  I haven’t implemented the entire interface and only have a couple of validations working (I will update the source code when it is all done).  Here is a couple of methods that I implemented.

public void SetEmail(string target, string violationMessage)
{
     Rules.Add(new ValidationRule(Validate.Email, violationMessage));
}
public void SetAsRequired(string target, string violationMessage)
{
    Rules.Add(new ValidationRule(Validate.Required, violationMessage));
}

As you can see, all I am really doing is just adding the validation rule to List of ValidationRules.  ValidationRule is a straight forward class and looks like this:

internal class ValidationRule
{
    public ValidationRule(Validate validate) : this(validate, null) { }
    public ValidationRule(Validate validate, string failureMessage)
        : this(validate, failureMessage, null) { }
    public ValidationRule(Validate validate, string failureMessage, object value)
    {
        Validate = validate;
        Value = value;
        if (failureMessage != null)
        {
            ErrorMessage = failureMessage;
        }
        else
        {
            //setup default error messages
            switch (Validate)
            {
                case Validate.Required:
                    ErrorMessage = "This field is required";
                    break;
                default:
                    ErrorMessage = "Field error";
                    break;
            }
        }

    }
    public readonly object Value;
    public readonly Validate Validate;
    public readonly string ErrorMessage;
}

The helper ClientSideValidation method simply loops through the collection of rules and generate the appropriate JavaScript.  Here it is

public static string ClientSideValidation(this HtmlHelper htmlHelper,
    string formName,
    object modelToValidate)
{
    var results = new StringBuilder();
    var rules = new StringBuilder();
    var messages = new StringBuilder();
    results.AppendFormat("$(\"#{0}\").validate({1}", formName, "{");
    results.AppendLine();
    rules.AppendFormat("rules: {0}", "{");
    messages.AppendFormat("messages: {0}", "{");

    var props = TypeDescriptor.GetProperties(modelToValidate.GetType());

    var propCounter = 0;
    foreach (PropertyDescriptor prop in props)
    {
        var generator = new JQueryValidationProvider();
        foreach (var attrib in prop.Attributes.OfType<AbstractValidationAttribute>())
        {
            var v = attrib.Build();
            v.ErrorMessage = v.ErrorMessage ?? "*";
            v.Initialize(new CachedValidationRegistry(), null);
            v.ApplyBrowserValidation(null, InputElementType.Undefined,
                                     generator, null, null);
        }

        if (generator.Rules.Count > 0)
        {
            if (propCounter > 0)
            {
                rules.Append(",");
                messages.Append(",");
            }
            rules.AppendLine();
            messages.AppendLine();
            rules.AppendFormat("{0}: {1}", prop.Name.ToLower(), "{");
            messages.AppendFormat("{0}: {1}", prop.Name.ToLower(), "{");
            rules.AppendLine();
            messages.AppendLine();

            for (var i = 0; i < generator.Rules.Count; i++)
            {
                var rule = generator.Rules[i];
                rules.AppendFormat("{0}", rule.GetRuleString());
                messages.AppendFormat("{0}", rule.GetMessageString());

                if (i < generator.Rules.Count - 1)
                {
                    rules.Append(",");
                    messages.Append(",");
                }
                else
                {
                    rules.Append("}");
                    messages.Append("}");
                }
                rules.AppendLine();
                messages.AppendLine();
            }

            propCounter++;
        }
    }

    rules.Append("},");
    messages.Append("}");
    rules.AppendLine();
    messages.AppendLine();
    results.Append(rules.ToString());
    results.Append(messages.ToString());
    results.Append("});");

    return string.Format("<script type='text/javascript'><!--{1}{0}{1}--></script>", 
                            results.ToString(), Environment.NewLine);
}

Changes

Halfway through this post, I read Steve Sanderson’s new post and Stephen Walther’s new post on validation, I made some changes to the code.  I agree with their point that the controller shouldn’t be responsible for initiating the validation and it should be done at a lower layer.  I refactored the code and my controller now looks like this

[AcceptVerbs("POST")]
public ActionResult Create(User user)
{
    try
    {
        user = new User();
        UpdateModel(user, new[] { "name", "email" });
        var service = new UserService();
        service.Save(user);
    }
    catch (RuleViolationException ex)
    {
        MvcValidator.PopulateModelStateWithErrors(user, ViewData.ModelState, ex);
    }
    return View(user);
}

 

The validation gets initiated at the service (business logic) layer and if there is a rule violation an exception is thrown.  I then take the exception and pass it to a helper method that populates the model state. Note: I could probably rewrite this so that the ModelState population happens before the exception throwing which will eliminate the call to the population method.

My view looks like this

<%=Html.ValidationSummary() %>
<form id="formCreate" name="formCreate" 
        action='<%=Url.Action("Create")%>' method="post">
    <label for="name">Name</label>
    <input type="text" id="name" name="name" />
    <br />
    <label for="email">Email</label>
    <input type="text" id="email" name="email" />
    <br />
    <input type="submit" value="Submit" />
</form>
<%= Html.ClientSideValidation("formCreate", ViewData.Model) %>

 

Now if I try to submit the form, the client script validation runs and I get these errors

clip_image001

If you get rid of client validation and only use server validation

to submit the form, the form would look like this

clip_image001[4]

Finally, here is the client JavaScript generated in the view:

<script type='text/javascript'><!--
    $("#formCreate").validate({
        rules: {
            name: {
                required: true,
                minlength: "3",
                maxlength: "25"
            },
            email: {
                email: true,
                required: true
            }
        },
        messages: {
            name: {
                required: "Username is required",
                minlength: "Username should be between 3 and 25 characters long",
                maxlength: "Username should be between 3 and 25 characters long"
            },
            email: {
                email: "Invalid email address",
                required: "Email is required"
            }
        }
    });
--></script> 

 

Pros & Cons

Here is what I think the pros of this design are:

  1. I love using model attributes to define validation rules
  2. I like that I only need 2 lines in my view
  3. I like that I don’t have to do anything in the controller other than catch an exception and call a helper method

The one thing I don’t like about this design is that it feels like there is a lot of dependencies.  I might need to refactor the code and move things around.  Here is my dependency diagram

image

Credit

This code was possible because of other people’s work:

Stephen Walther – link

Steve Sanderson – link and link 2

Hamilton Verissimo – link

Rick Strahl – link

Scott Guthrie – link

Source Code

Click here to download the rough-quality source code.

Let me hear what you think of this design.  What’s wrong with it?  What’s right?  Should I put this up on codeplex?

Deciding Between ASP.NET MVC and WebForms

I am trying to create a decision flowchart for my ASP.NET MVC book and wanted to get some community feedback.  Does this diagram make sense?  What other factors should one consider that should make it into the chart?

image

Things to Note

I have tried to use the general consensus of the community for each decision.  For example, some might argue that MVC is better for prototyping but I would say the majority would disagree.

Keep in mind that these choices are not set in stone and are not mutually exclusive but are more like a guide to which platform would be better suited to satisfy a particular requirement.  For example you might want to use TDD but still end up choosing on WebForms.  (I should probably assign a weight to each question)

The "No" branch doesn’t mean exactly NO.  I mean, answering No to "Want cleaner HTML?" doesn’t mean you have something against clean HTML or you want crappy HTML – no one wants that.  Think of the question in terms of "is clean html important to you?" 

Let me hear your feedback below and I will incorporate it in version of 2 of the diagram and post it back on the blog.  Hopefully, this will help someone choose between ASP.NET MVC and WebForms on a new project.

Also, I don’t think a flowchart diagram is the best type of diagram for this type of decision tree.  Can you suggest a better format?