Tuesday, August 20, 2013

Project Seed for ASP.Net WebAPI + AngularJS + Bootstrap

Project Seed: A 'ToDo' app built with MS ASP.Net WebAPI + MSSQL + AngularJS + Bootstrap

Poorman's Development Environment:
- Windows XP SP3
- MS Visual Studio Web Developer 2010 Express SP1 + 'Package Manager Console'
- MS SQL Server 2008 R2
- MS SQL Server Management Studio 2008 R2 10.50.1617.0
- MS .NET Framework 2.0.50727.3649


A. Restful API: Setting up ASP.Net WebAPI project

0. Steps to create a ASP.Net WebAPI project with Visual Studio:
i. File > New Project... > Visual C# > Web > ASP.NET MVC 4 Web Application
ii. Name: ToDoApp_WebAPI_MSSQL_AngularJS and click OK
iii. Select a template: Web API (Note! View engine: Razor)

1. JSON as primary data-exchange format: Paste the below code in the member function 'Register' present in the following class file 'WebApiConfig.cs'.

// Remove default XML data-exchange format, so as to use JSON
config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(
config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml"));
             
2. The Model: Now, create the ToDo's data-model class in the 'Models' folder, for example a class file called '/Models/ToDoItem.cs':

namespace ToDoApp_WebAPI_MSSQL_AngularJS.Models
{
    public class ToDoItem
    {
        public int ToDoItemID { get; set; }
        public String ToDo { get; set; }
        public byte Priority { get; set; }
        public DateTime? DueDate { get; set; }
    }
}

3. Importantly! Clean your project & Rebuild your project

4. Create controller class for the above created data-model in the 'Controllers' folder. Which will automatically creates set of default Restful resources + Database tables on MSSQL DB.

i. Controller Name: 'ToDoController'
ii. Template: API controller with read/write actions, using Entity Framework
iii. Model class: ToDoItem (ToDoApp_WebAPI_MSSQL_angularJS.Models)
iv. Data context class: <New data context...> ToDoApp_WebAPI_MSSQL_AngularJS.Models.ToDoContext

5. Now, run the project & test your web app on your faviourate web-browser. For example with this URL:
http://localhost:????/api/todo


B. Pseudo dataset: Generate pseudo dataset on MSSQL database

1. Enable-Migrations with the database using the "Package Manager Console". Which will create a 'Configuration.cs' after creating a detected Database for your application.

2. Now, Add your logic for generating pseudo dataset using your data-model in "Configuration.cs", as below:

protected override void Seed(ToDoApp_WebAPI_MSSQL_AngularJS.Models.ToDoContext context)
        {
            var r = new Random();
            var items = Enumerable.Range(1, 15).Select(o =>
                            new ToDoItem
                            {
                                ToDo = o.ToString(),
                                Priority = (byte)r.Next(10),
                                DueDate = new DateTime(2012, r.Next(1,12), r.Next(1,28))
                            }
                        ).ToArray();
            context.ToDoItems.AddOrUpdate(item => new { item.ToDo }, items);
        }
     
3. Now, run Update-Database command in "Package Manager Console" in-order to inject random dataset to MSSQL database.

4. Now, run the Project & test your web app on a web-browser. For example with this URL:
http://localhost:????/api/todo


C. Frontend: AngularJS + Bootstrap setup  

1. With the help of "Package Manager Console", download the necessary libraries for your frontend:
i. Install-Package angularjs
ii. Install-Package Twitter.Bootstrap

2. Importantly! Clean your project & Rebuild your project

3. Create an 'index.html' file in the projects root directory, using the below html:

<!DOCTYPE html>
<html ng-app="ToDoApp" xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="Scripts/jquery-1.9.1.js"></script>
<script src="Scripts/bootstrap.js"></script>
<script src="Scripts/angular.js"></script>
<script src="Scripts/angular-resource.js"></script>
<script src="Scripts/app.js"></script>
<link rel="stylesheet" type="text/css" href="Content/bootstrap/bootstrap.css" />
<title>Amazing Todo</title>
</head>
<body>
<div class="container">
<div ng-view></div>
</div>
</body>
</html>

4. Create an 'app.js' file in the '/Scripts' directory, using the below content:

//Constructor
var ToDoApp = angular.module('ToDoApp', ['ngResource']).config(
function ($routeProvider) {
$routeProvider.
when('/', { controller: ListController, templateUrl: 'list.html' }).
otherwise({ redirectTo: '/' });
}
);

//Factory for configuring the DB query
ToDoApp.factory('ToDo_Resource', function ($resource) {
return $resource(
'/api/todo/:id',
{ id: '@id' },
{ update: { method: 'PUT'} }
);
});

//Controller
var ListController = function ($scope, $location, ToDo_Resource) {
$scope.items = ToDo_Resource.query();
};

5. Create a 'list.html' file in the projects root directory, using the below bootscrap components:

<table class="table table-striped table-condensed table-hover">
    <thead>
        <th>
            ToDo's
        </th>
        <th>
            Priority
        </th>
        <th>
            DueDate
        </th>
    </thead>
    <tbody>
        <tr ng-repeat="item in items">
            <td>
                {{item.ToDo}}
            </td>
            <td>
                {{item.Priority}}
            </td>
            <td>
                {{item.DueDate | date:mediumDate}}
            </td>
        </tr>
    </tbody>
</table>

6. Now, run the Project & test your web app on a web-browser. For example with this URL:
http://localhost:????/index.html


Seed mercurial-repository:
This entire project-seed can be cloned from Bitbucket, here's the repository's URL:
https://bitbucket.org/nshetty/todoapp_asp.netwebapi_mssql_angularjs_bootstrap

Related references:

Tuesday, December 4, 2012

Part1 - Can Gevent and Socket.IO be an event-driven, asynchronous IO/Networking infrastructure for building near-realtime web applications, keeping code-ability at the centre of it?

Keywords: Event-driven architectural style, Asynchronous IO/Networking, Gevent a Python based event library, Socket.IO comet library, Near-realtime web application

An important question while choosing a technology stack for an event-driven architecture (i.e. problem domain) is:
What is the programming paradigm that would be programmer friendly? [Note! Programmer friendly refers to "lities" like code maintainability, code scalability, code testability, among others.]

The status quo for implementing event-driven infrastructure is => to use call-backs. Of-course, devil is in the details... call-backs have their +ves, but lots of -ves (references: 1, 2) when we seek for the above mentioned "lities". 

Instead, think about... what if programmers could use imperative programming style to tackle this problem domain. Well, the solution don't lie in shifting of programming paradigm itself, but in the possibility to isolate recurring implementation details like call-backs. This gets us to acknowledging the power of DRY principle. Perhaps, what if such a DRY princip can be released with a set of programming language features:
    • Automatically takes care of creating call-backs
    • Creation of a call-back is dependent on a given routine, that is if a routine acts as blocking-type (i.e. blockage of the control flow)
    • Possibility to manually declare blocking-type routines
  Gevent API for Python is such an attempt to incorporate the above mentioned DRY princip into the programming language. In addition, as a side effect this API achieves a clear cut imperative programming style. Which means that call-backs are implicitly present but also make room for explicit declaration where needed.

Importantly, I am already smelling the "lities" being satisfied... is it? Well, in-order to answer this question... it will take some experimenting with the Gevent API. I hope this will be a path to enlightenment and to be convinced of this API friendliness towards code-ability.

Upcoming post will produce a simple prototype which will bring all the above mentioned technology stack and study it further. Here's heads-up to the prototype's repository.