Category: MVC

MSWebDay – What I took away from it

Today, Feb 16th, I attended MSWebdevday ran by Microsoft in Glasgow which was an event covering all things web related from Microsoft, the speakers were @christosmatskas, @thebeebs and @martinkearn and was an all day event.

The Schedule for the day covered various topics and it was great to learn so many new things and get my first glimpse at some new technologies, I always love learning something new, and I even sat next to the illustrious Gary Ewan Park, someone who I have chatted to a few times on twitter but not every managed to meet.

Ok so lets cover the actual event:-

The first talk was by on What’s New in ASP.Net Core 1.0 and was a tour of the new features, how to get it, how to use it, whats new, whats no longer there and he also talked about how you can just take the files and drop them into a folder when deploying, there’s no gac, you can just deploy the Core files in a folder alongside your code, this is very neat, its cross-platform, and it means you could have the same site running under different version of Core going forward should you choose to or need to have this.

The second Talk was Building with JavaScript Task Runners, this was mainly about how to get gulp, how to set it up and how to run some tasks to minify your css, javascript files and all that good stuff, how to add it into Visual Studio as a build step after you compile your code, showed an example gulp file and lots more.

The third talk was Entity Framework Core 1.0, and covered EF and how to use it, how to use code first and also mentioned EF6 how its improved greatly from previous versions and why you should choose this version at the moment whilst EF Core 1.0 is still being worked on and has the tooling added to it for the Core 1.0 release.

The fourth talk was APIs: the cogs behind the machine and this talk was about api’s and mainly web api and how in Core 1.0 there is no MVC and WebAPI its just one thing now and your controller is an API controller, so no need for MVC and WebAPI there is just the controllers now which kind of merge both together.

The fifth talk was Dev Ops in Azure and this covered deploying your website to Azure, making changes, showing the changes, getting the publisher file for using in side Visual Studio and publishing your changes from Visual Studio using Git int his example to deploy your changes from within VS up to the new Azure portal.

The sixth talk was Hitchhikers Guide to JavaScript, this talk focused on ECMAScript and the future of JavaScript and basically how a lot more code that we write will be JavaScript and we saw examples of the features coming in the next few years etc.

The seventh talk was Web Performance and how to check your websites performance using tools like YSlow and Google Page Speed etc and then how to go about making it make far less requests, cache JavaScript, enable IIS features and how to optimise images etc to make your website perform much faster that it currently does.

The eight talk was Single Page Applications and was about KnockoutJS and Angular, talking about Angular 2 and how it makes use of TypeScript and showed code covering KnockoutJS and AngularJS.

The ninth talk was about Hybrid Web Apps and how you can create application that can appear as Windows 8/10 tiles, make use of Microsoft Office and showed some very neat stuff using ManifoldJS which is itself very cool stuff.

Other stuff mentioned
I wrote some notes during the talks (should have taken a lot more) but a couple of things I need to look at are listed below:-

Summary
The event was great, full days learning, a lot of content covered, great speakers and good turn out. Spoke to some guys I chat to on twitter and all in all an awesome day spent learning some new stuff. There was a lot of content, I’ve missed half of it I’m sure so take a look at the slides on the site at MSWebdevday.

Dear Microsoft can we have some more of these days please? – especially Azure and Core related content.



ElmahR – monitor errors in your app using a dashboard

If your unfamiliar with Elmah and/or ElmahR then please take a quick look here.

If you’re using Elmah but haven’t taken advantage of ElmahR then read on.

If you have one or more application(s) which currently use Elmah then you can very easily add in ElmahR which gives you a superb dashboard from where you can monitor either one or all of you applications which log errors.

The dashboard is basically one webpage which makes very nice use of SignalR to display information regarding errors thrown by your application(s), so if you deploy something and you monitor this page and see the error count for your application counting up quickly then you know you have a problem. You can use the dashboard to monitor a number of applications on different environments for example.


Existing/New Web Application

  • Either create a brand new test web application or you can use an existing web application – add ElmahR to this application using the Nuget package as below:-
    ElmahR
  • Ok now that we have added ElmahR to a web application we need to configure it accordingly, open up the web.config and look for the elmah section, should look something like this:-
  • elmah1

  • Important – The sourceId setting needs to match the sourceId setting in our dashboard application’s web.config

DashBoard

  • Now lets create our dashboard, so create a new MVC or Web application, then add the Nuget package as below:-
    ElamhrDash
  • Now we need to edit the dashboard’s web.config so that the sourceId’s match, shown below:-
    elmahr3

Testing ElmahR is working

  • Within your web application we want to test that ElmahR is set up and working correctly, to do this we need to have an error generated, so deliberately add an exception, such as a throw new NotImplementedException() or similar into an area you can test quickly (e.g. index actionresult within the home controller in MVC)
  • Run the dashboard application, which should look something like this:-

    elmahr5

  • Then run your web application and browse to the page which will generate an error so we can see if it logs as we expect.
  • If you have everything configured correctly then you will see the error count change in the dashboard application, like so:-
    elmahr6

TroubleShooting

  • If you don’t see your application logging errors on the dashboard it’s usually the sourceId element or the targetUrl element within your web.config

Hope you find this of use and start using ElmahR.

If you get stuck or something isn’t working add a comment.




New MVC Learning Resource – feedback requested

redgate The developers at Redgate are working on a new resource for learning MVC and are looking for you’re feedback – you can take a look here and give them your feedback on how to improve it and make it grow.

content

Above is a sample of what there is currently – more to come very shortly.

Enjoy.



KnockoutJS – what I’ve learned so far

I have been using KnockoutJS at work for the last few weeks and thought it might be an idea to blog about my findings whilst using KnockoutJS within an MVC 4 project, so here goes: –

  • With KnockoutJS you can get a really slick user experience if you show discipline in structuring your code, you can separate out your concerns using unobtrusive JavaScript – i.e. don’t put your JavaScript in the HTML, yes add data-bind attributes but that should be all you need, your JavaScript can be referenced from a file within a JS folder or similar keeping your HTML clean and free from being polluted by lots of inline JavaScript.

  • If you’re wondering how you go about going from your MVC model and working with this in KnockoutJS then look no further than KnockoutJS mapping. This plugin will take your existing Model from c# and convert it into what you will use within KnockoutJS, for example if in your model you have a string[] defined like so:-
    [sourcecode language=”csharp”] public string[] EmailAddresses { get; set; }
    [/sourcecode] then the mapping plugin converts this to an observableArray, and if you have a simple string property such as: –
    [sourcecode language=”csharp”] public string Email { get; set; }
    [/sourcecode] then the plugin will map this to a knockout observable for you.

  • When using ObservableArrays note that the number of items in the array is tracked – not the actual values within the array – this is important if, if the front end requires updated to the values within the array then you need to make the items within the ObservableArray observable also.

  • Take a look at the ko.utils code mentioned here for some hidden gems when working with KnockoutJS.

  • Dont store a lot of information in observables if you don’t have to, it’s not a good idea to store 10,000 records in an observable array and then bind that to a grid (Only store what you need in observables)

  • It can be a good idea to display on your page the contents of your viewmodel whilst you’re debugging so you can see what the observable and observable arrays you’re using contain

    [sourcecode language=”csharp”] <div id="debug" style="clear: both">
    <hr />
    <h2>Debug</h2>
    <div data-bind="text: ko.toJSON($data)" />
    </div>
    [/sourcecode]
  • More soon as I use it more and more, hope that helps.




Error handling using aspect-oriented programming (AOP)

Code become’s messy with error handling logic all over our code, wouldn’t it be nice to be able to log the error, the offedning method name and the line number of the code that caused the error in the first place.

If you’ve done any MVC development then you are already familiar with AOP, [HandleError] is an example of an aspect and with very little effort indeed you can create your own. Creating an aspect means you can reuse logic for tracing, error handling and more very easily.

At work we use PostSharp for our AOP aspect-oriented programming and its doesn’t get much easier. The guys even give you an add on in visual studio and it walks you through how to go about learing AOP and how to create aspects using PostSharp – the tutorial is superb and very well thought out.

We have a class library logging class which we use as an aspect using Postsharp and this means that we can add a [Catch] attribute to the method and we now have error logging for this new method:-

[sourcecode language=”csharp”] [Catch] public MyNewMethod()
{
throw new applicationException();
}
[/sourcecode]

And that is it, download the demo and give it a try its so easy but quite powerful – I recommend you take a look.




AspConf – My Review

Last week we had AspConf – “aspConf is a virtual conference focused on one thing: showcasing the ASP.NET stack as the platform for great web applications.

Over 2 days they had 5 virtual rooms used to present lots of fascinating stuff on .Net, including talks about all manner of things in the Asp.Net world.

The sessions on both days covered topics such as, Async in .Net 4.5, Glimpse, TDD, Azure and Cloud Computing and lots lots more, you can read more about the sessions here.

Although it had some technical difficulties, due to its popularity I may add, the conference is an awesome way to learn for free – and free is always good. It’s a superb way to learn about content you havent had time to look at it, or new technologies you havent heard of. Hopefully next year they might try to use something different from livemeeting.

If you missed any of the session then fret not, most of them if not all of them were recorded and put up on Channel 9 here

I only managed to see sessions from day 2 so I am off to go watch more content on Channel 9 – a great resource for free learning.



ElmahR – Elmah fused With SignalR

If your using Elmah then you’ll be familiar with most of this blog post, if not then don’t worry Elmah stands for Error Logging Modules and Handlers and is used to log unhandled exceptions to the file system, event log, databases or even have it email you the errors.

ElmahR was created by Roberto Vespa (@wasp_twit) and his blog on ElmahR can be found at:- Roberto’s blog

The basics – ElmahR uses Elmah and SignalR to create a dashboard page where you can monitor any unhandled exceptions in all of the applications you have running which use Elmah, that means if you have 5 websites in production you can have one web page monitor them all.

ElmahR Dashboard

To view an example dashboard running on app harbor.

ElmahR uses SignalR which again you can read more on Scott hanselman’s blog

Now lets see how we go about setting this up to work with a new MVC 3 project – the same steps apply to adding it to an existing web application.

  • Create a brand new web application, mvc or normal web app works fine.
  • Using Nuget add the following packages to your blank MVC solution, so add Elmah and JQuery.
  • Once both added follow the configurations steps here
  • You can install the Nuget Package:- ElmahRSource



RavenDB CRUD – How To

I always wondered how easy it would be to do a RavenDB CRUD (Create, Read, Update, Delete) example, so lets create a simple MVC application which we can use to create, read, update and delete.

The following is some very basic code and yes you guessed it not for production but more of a quick sample to get you on your way with RavenDB and adding, editing and deleting documents.

We shall use a product model as our basis for the demo application – let’s get started.

  1. Create a blank MVC solution to begin with
  2. Using Nuget add in the Nuget package called RavenDB
  3. Lets setup RavenDB as we require within the global.asax.cs file as below:-
    [sourcecode language=”csharp”] protected void Application_Start()
    {
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    Store = new DocumentStore { ConnectionStringName = "RavenDB", DefaultDatabase = "Products" };
    Store.Initialize();
    }
    [/sourcecode] Note:- I have added in a DefaultDatabase config value above which means I have created a new Products Raven Database within the RavenDB Management Studio called Products, if you don’t do this and just want to use the default database then remove the part DefaultDatabase = “Products”

  4. Add a class into the Models folder called Product as below:-
    [sourcecode language=”csharp”] public class Product
    {
    public string Id { get; set; }
    public string CategoryId { get; set; }
    public string SupplierId { get; set; }
    public string Name { get; set; }
    public string Code { get; set; }
    public decimal StandardCost { get; set; }
    public decimal ListPrice { get; set; }
    public int UnitsOnStock { get; set; }
    public int UnitsOnOrder { get; set; }
    public bool Discontinued { get; set; }
    }
    [/sourcecode]
  5. Now that we have our Model, let’s go ahead and add in a couple of controllers. We will use a base controller when working with our RavenDB project so firstly create a RavenDB Controller, to do this right-click on controllers folder and then select Add then choose Controller, select Empty Controller.
  6. Paste this code into your RavenController:-
    [sourcecode language=”csharp”] public class RavenController : Controller
    {
    public IDocumentSession _session { get; private set; }

    public const int DefaultPage = 1;
    public const int PageSize = 10;

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
    if (filterContext.IsChildAction)
    return;
    _session = MvcApplication.Store.OpenSession();
    base.OnActionExecuting(filterContext);
    }

    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
    if (filterContext.IsChildAction)
    return;

    using (_session)
    {
    if (filterContext.Exception != null)
    return;

    if (_session != null)
    _session.SaveChanges();
    }
    }

    protected int CurrentPage
    {
    get
    {
    var s = Request.QueryString["page"];
    int result;
    if (int.TryParse(s, out result))
    return Math.Max(DefaultPage, result);
    return DefaultPage;
    }
    }
    }
    [/sourcecode]

  7. Lets now add a ProductController and this time choose, Controller with empty read/write actions as below:-
    ProductController
  8. We will start off by adding in some code which I have already written for the methods which we will use on the Products Controller, add them into your code:-
    [sourcecode language=”csharp”] public class ProductController : RavenController
    {
    //
    // GET: /Product/

    public ActionResult Index()
    {
    var model = _session.Query<Product>()
    .Paging(CurrentPage, DefaultPage, PageSize)
    .ToList();

    Mapper.Map<List<Product>, List<ProductViewModel>>(model);

    return View(model);
    }

    //
    // GET: /Product/Details/5

    public ActionResult Details(string id)
    {
    var model = _session.Load<Product>(id);
    return View(model);
    }

    //
    // GET: /Product/Create

    public ActionResult Create()
    {
    var model = new Product();
    return View(model);
    }

    //
    // POST: /Product/Create

    [HttpPost] public ActionResult Create(Product product)
    {
    try
    {
    _session.Store(product);
    return RedirectToAction("Index");
    }
    catch
    {
    return View();
    }
    }

    //
    // GET: /Product/Edit/5

    public ActionResult Edit(string id)
    {
    var model = _session.Load<Product>(id);
    return View(model);
    }

    //
    // POST: /Product/Edit/5

    [HttpPost] public ActionResult Edit(Product product)
    {
    try
    {
    _session.Store(product);
    return RedirectToAction("Index");
    }
    catch
    {
    return View();
    }
    }

    //
    // GET: /Product/Delete/5

    public ActionResult Delete(string id)
    {
    var model = _session.Load<Product>(id);
    return View(model);
    }

    //
    // POST: /Product/Delete/5

    [HttpPost, ActionName("Delete")] public ActionResult DeleteConfirmed(string id)
    {
    try
    {
    _session.Advanced.DatabaseCommands.Delete(id, null);
    return RedirectToAction("Index");
    }
    catch
    {
    return View();
    }
    }

    public ActionResult StoreSomeProductInDatabase()
    {
    var product = new Product
    {
    Name = "Product Name",
    CategoryId = "category/1024",
    SupplierId = "supplier/16",
    Code = "H11050",
    StandardCost = 250,
    ListPrice = 189
    };

    _session.Store(product);
    _session.SaveChanges();

    //return Content(product.Id);
    return RedirectToAction("Index");
    }

    public ActionResult InsertSomeMoreProducts()
    {
    for (int i = 0; i < 50; i++)
    {
    var product = new Product
    {
    Name = "Product Name " + i,
    CategoryId = "category/1024",
    SupplierId = "supplier/16",
    Code = "H11050" + i,
    StandardCost = 250 + (i*10),
    ListPrice = 189 + (i*10),
    };
    _session.Store(product);
    }

    _session.SaveChanges();

    //return Content("Products successfully created");
    return RedirectToAction("Index");
    }

    public ActionResult GetProduct(int id)
    {
    Product product = _session.Load<Product>(id);
    return Content(product.Name);
    }

    public ActionResult LoadAndUpdateProduct()
    {
    Product product = _session.Load<Product>("products/5");
    product.ListPrice -= 10;
    _session.SaveChanges();
    return Content("Product 5 successfully updated");
    }

    public ActionResult DeleteProduct(int id)
    {
    Product product = _session.Load<Product>(id);
    if (product == null)
    return HttpNotFound("Product {0} does not exist");
    _session.Delete(product);
    _session.SaveChanges();
    return Content(string.Format("Product {0} successfully deleted", id));
    }

    /// <summary>
    /// Get all the products that are available for sale (discontinued equal to false) ordered by the product’s list price
    /// </summary>
    /// <returns></returns>
    public ActionResult GetDiscontinuedProducts()
    {
    var products = from product in _session.Query<Product>()
    where product.Discontinued == false
    orderby product.ListPrice
    select product;

    return View(products.ToList());
    }
    }
    [/sourcecode]

  9. Ok so above we added a lot of code but this is good as this is the entire product controller and will allow us to add/edit/delete new products into RavenDB.
  10. I also added in a couple of methods for creating some test data, and also a method for returning discontinued products, mainly to show how you can go about doing this.
  11. Some screen shots are below, note they show me using RavenDB Profiler and MiniProfiler:-

    Crud 1

    Crud 2

    Crud 3

The code for this article is up on github here.
For more on RavenDB have a look at my other RavenDB posts here.

Please leave a comment, ask a question, find a bug or anything like that please let me know.




Host your RavendDB based MVC app on Appharbor

RavenDBIn this blog post I will walk through how to host an MVC application which uses RavenDB as the back-end document database hosted up on Appharbor, Appharbor now allows us to host RavenDB in the cloud.

In the blog post I am going to make several assumptions, the post itself is more to do with getting an application deployed and running up on AppHarbor using RavenDB as the document database.

I am assuming you have you have a github account and know how to get your code up onto github, an Appharbor account and know how to deploy your code to github to Appharbor.

If you need some help with doing this then check here.

Ok lets create a brand new MVC Web application project, I used MVC 3 application

Raven2

And then I chose the internet template.

Raven3

You can either download RavenDB from RavenDB.net or use Nuget to get RavenDB. For the demo I just installed it using Nuget
as follows, within Visual Studio goto Tools, Library Package Manager and then select Package Manager Console and then type:-

Raven

RavenDB is now downloaded using NuGet and you will find it within the packages folder in the same location on disk as your project solution files, to start RavenDB locat the packages folder and then go to the RavenDB.1.0.616 folder and then the Server folder and double click on Raven.Server.exe as below:-

Raven4

By default RavenDb runs on http://localhost:8080, once started you can view the Raven Studio from within a browser, and you should see something like this:- (if it says Create Sample Data then click on the button to create sample data)

Raven10

Moving back to our MVC Application we now need to wire a couple of things up to use RavenDB as below:-

In the global.asax add in the following in the Application_Start event:-

[sourcecode language=”csharp”] protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();

RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);

var parser = ConnectionStringParser<RavenConnectionStringOptions>.FromConnectionStringName("RavenDB");
parser.Parse();

Store = new DocumentStore
{
ApiKey = parser.ConnectionStringOptions.ApiKey,
Url = parser.ConnectionStringOptions.Url,
}.Initialize();
}
[/sourcecode]

Add in a connection string in your web.config as follows:-

[sourcecode language=”csharp”] <connectionStrings>
<add name="RavenDB" connectionString="Url=http://localhost:8080" />
</connectionStrings>
[/sourcecode]

All new Controllers will inherit from RavenController which is below:-

[sourcecode language=”csharp”] public class RavenController : Controller
{
public IDocumentSession RavenSession { get; private set; }

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.IsChildAction)
return;
RavenSession = MvcApplication.Store.OpenSession();
base.OnActionExecuting(filterContext);
}

protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.IsChildAction)
return;
using (RavenSession)
{
if (filterContext.Exception != null)
return;

if (RavenSession != null)
RavenSession.SaveChanges();
}
}
}
[/sourcecode]

Below is some example code for some basic CRUD.

[sourcecode language=”csharp”] public class AlbumController : RavenController
{
public ActionResult Index()
{
var model = this.RavenSession.Query<Album>().ToList();
return View(model);
}

public ActionResult Create()
{
var model = new Category();
return View(model);
}

[HttpPost] public ActionResult Create(Album album)
{
this.RavenSession.Store(album);
return RedirectToAction("Index");
}

public ActionResult Edit(string id)
{
var model = this.RavenSession.Load<Album>(id);
return View(model);
}

[HttpPost] public ActionResult Edit(Album album)
{
this.RavenSession.Store(album);
return RedirectToAction("Index");
}

public ViewResult Details(string id)
{
var model = this.RavenSession.Load<Album>(id);
return View(model);
}

public ActionResult Delete(string id)
{
var model = this.RavenSession.Load<Album>(id);
return View(model);
}

[HttpPost, ActionName("Delete")] public ActionResult DeleteConfirmed(string id)
{
this.RavenSession.Advanced.DatabaseCommands.Delete(id, null);
return RedirectToAction("Index");
}
}
[/sourcecode]

Within Appharbor choose RavenDB as an add-on, appharbor will provision you with a connection string if you choose
RavenDB as an add-on, wait a couple of seconds and you will be supplied with a connection string for your RavenDB instance in the cloud.

Step 1

Step1

Step 2

Step 2

Step 3

Step 3

Step 4
Step 4

Step 5
Step 5

This setting is the one you will change to within your web.config, for testing locally use http://localhost:8080 but for deploying to the cloud use the connection string setting supplied to us by Appharbor.

Getting RavenDB from NuGet means quite a large download, we dont want to have to upload all of this content to github so we can do a nice little thign within our solution, roght click on the entire solution within Visual Studio and choose:-

Package Restore

This means our github repository doesnt have to contain all of the Nuget packages and will pull them down for us when building.

Once your code is building and running locally send it up to github and use the service hook to deploy to Appharbor.

If you come across any build errors then you may have to turn customerrors=”Off” in your web.config as well as checking the build log on Appharbor to see what went wrong.

At this point we should have a working MVC application which is using RavenDB as the back-end document database – sweet.

If I missed anything or anyone has any questions or comments please tweet me @gsuttie or leave a comment.




Host your MVC app in the Cloud with AppHarbor

Deploy your MVC 3 application to the cloud and have it hosted for free, you can even get 20MB SQL Server for free should your app use a SQL database backend.

If your unfamiliar with Appharbor let me introduce you.

AppHarbor

“AppHarbor is a fully hosted .NET Platform as a Service. Appharbor can deploy and scale any standard .NET application.”

Deploy and host host your application for free using GitHub to publish the content to Appharbor – couldnt be easier and ultra fast, and did I mention its free?

GitHub

Basically build your application locally – put it up onto Github, setup the Github service hook ( cut and paste 2 lines) and job done – AppHarbor will build your code and deploy it and host it in the cloud for you!

The following are the steps to deploying a blank MVC 3 project to Appharbor using Git and Github, if your unfamiliar with Git and Github then its worth spending some time reading up on both, Git is very straight forward to get going and GitHub is the site to host your git content.

I will assume you have git installed and setup a local repository on your machine – let’s get started.

  1. Open Up Visual Studio 2010 and create an empty MVC 3 Application, I chose an Internet Application and didn’t select to add a Unit Test Project.
  2. I changed the text on the main page that will do for now. Then I copied the contents of the solution and the folder to my Github local repository folder.
  3. Go to Github and create yourself an account – this is free and allows you to put up your code – very useful for open source projects or you can use it to publish to Appharbor like we are about to do.
  4. Create a new Repository on GitHub as below and GitHub will show you the steps to adding the code to your repository on GitHub, similar to the screen shot below.

    Github Repo

    Go ahead and follow these steps to add your content onto GitHub.

  5. Now we want to add a .gitignore file into the git repository so that when we deploy to AppHarbor it builds without any issues. Create a .gitignore file and add this into your repository – the contents of my .gitignore file was as follows:-

    [Bb]in
    [Oo]bj
    *.suo
    *.user
  6. At this point our source code is up on GitHub and now we want to deploy it from GitHub to AppHarbor – this step is very easy indeed and makes everything worthwhile and definitely worth any effort in having to learn git and setup accounts on both GitHub and AppHarbor.
  7. Log onto your AppHarbor Account and then create a new application as below:-

    AppHarbor

  8. Now click on the Build URL link on the blue part of the screen shot below:-

    AppHarbor

    This copies the url you need to paste into GitHub in order for it to deploy your code to AppHarbor, firstly paste this link from your clipboard into notepad.

  9. Here is the url for a potential app:-

    AppHarbor Build URL

  10. Ok now go back to GitHub and go to the admin link once you are on the page displaying your GitHub repository.

    GitHub Admin Link

  11. Click on Service Hooks on the left hand side and then select AppHarbor – this is where you need to be careful to paste in the Slug from the notepad link we have and then paste in the authorization code into the correct part within GitHub as below:-

    AppHarbor Details

  12. Back to AppHarbor and we should see something like the screenshot below, AppHarbor has built my code and deployed it, clicking on the ‘Go To Your Application’ link will show you the app deployed to the url for your site hosted on AppHarbor – free.

    View App

Conclusion
AppHarbor is really cool and very handy indeed, after deploying your first app you can deploy straight from GitHub just by pushing up file changes. Its superb, also comes with a host of add-ons, please go check it out now.