Web app woes: The database needs another field

Standard

After a few weeks on client side coding. I realize I need another field in the database and in the DTO. So I need to leave my client side project and enter the dark dungeons of the server side.

Add a field to the dev database. Add the property to the DTO. Deploy a new version of the dev dll’s. And later repeat the same thing for the production database and deploy the dll scheduled at night to the production web server.

Small thing? Why complain? Well, when I’m into client side flow dev, I dislike leaving my comfort zone for quite some time just to do such a futile task.

Rapid Single Page Application development with typescript, couchdb and domo

Standard

OK, this might be a pretty odd way of creating applications. But this method met a few goals I had for rapid application creation:

  1. Create it in Typescript only.
  2. Use some kind of document database from client side javascript.
  3. Run and debug locally.
  4. Publish easily.

My application iterations looks like this:

  1. Make code changes in Typescript.
  2. Test it locally.
  3. Publish to Github. Test it online.
  4. Update one single file to the live web server (Iriscouch).

The database is the web server

The web server is actually a Couchdb instance running on host Iriscouch (free for small usage). Couchdb is a document database that can host html, js and other web resources.

The entire application in one file
The full (compiled) application is bundled into one javascript file. Other than that I only use a minimal html that references that js. Even the css and the html are created from within the javascript application, it does so with the help of Dōmo “Markup, style, and code in one language”.

In my couchdb instance I have a database document named “test”. And within that I have three file attachments:

  • index.html
  • couchapp.min.js
  • github.html

index.html is the base html document that hosts my script, it looks like:

<!doctype html>
<html>
  <script src="couchapp.min.js"></script>
</html>

A nice file structure within Visual Studio + one click build everything into one js

The bundled script contains (for now) jquery.js, jquery.couch.js, domo.js and my own scripts mymodule.js and app.js.

app.js is the main application file, within that I call functions in the referenced files.

Both my own javascript files are compiled from Typescript. They are bundled on build in Visual Studio with the help of Web Essentials – so whenever I build the project I get an updated couchapp.js (and couchapp.min.js).

The couchapp.js.bundle looks like this

<?xml version="1.0" encoding="utf-8"?>
<bundle minify="true" runOnBuild="true">
  <!--The order of the <file> elements determins the order of them when bundled.-->

  <file>/lib/jquery.js</file>
  <file>/lib/jquery.couch.js</file>
  <file>/lib/domo.js</file>

  <file>/scripts/mymodule.js</file>
  <file>/scripts/app.js</file>

</bundle>

When I have made a new version I need to manually upload the bundled js to iriscouch. However before I do that I can run the github.html from iriscouch, which runs the current script from my github repository. Github.html looks like this:

<!doctype html>
<html>
  <script src="https://raw.github.com/joeriks/couchapp/master/couchapp.js"></script>
</html>

The source is at Github : https://github.com/joeriks/couchapp

You can see the application live at https://joeriks.iriscouch.com:6984/docs/test/index.html

And the “develop version” is at https://joeriks.iriscouch.com:6984/docs/test/github.html

Current version of the source

///<reference path="../defs/jquery.d.ts"/>
///<reference path="../defs/couch.d.ts"/>
///<reference path="../defs/domo.d.ts"/>
///<reference path="mymodule.ts"/>


function opacity(pct) {
    return { opacity: String(pct / 100), filter: "alpha(opacity=" + pct + ")" }
}

HTML({ lang: "en" },
  HEAD(
    TITLE("A sample of a typescript application within a couchdb"),
    STYLE({ type: "text/css" },
      STYLE.on("body", { textAlign: "center", fontSize: 50 }),
      STYLE.on("h1", opacity(50), { background: "#000", color: "#fff" })
    )
  ),

  BODY(
    H1("A sample of a typescript application within a couchdb"),
    DIV({ id: "databases" }),
    DIV(
        LABEL("name"),
        INPUT({ id: "name" })
        ),
    DIV(
        LABEL("value"),
        INPUT({ id: "value" })
        ),
    
    BUTTON({ id: "create" }, "Click to create new document"))
);

$("#create").click(() => {

    $.couch.login({ name: 'test', password: 'test' });
    $.couch.db("docs").saveDoc(
        {
            name: $("#name").val(),
            value: $("#value").val()
        }, {
            success: (data) => {
                alert("Saved as " + data.id);
            }
        });
});

Using SignalR to build an Api (in Umbraco, WebMatrix or MVC)

Standard

I wrote a blog post the other day about using plain Razor scripts to create an easy to maintain Api on an Umbraco site. It’s a very straight forward way to make ajax-calls possible. However in reality I think many would say razor files is just not the right choice for server functionality like this, and for bigger solutions I do agree on that.

The Umbraco standard way would be to use /Base. And the new AspNet WebApi would be another obvious alternative for it.

But in this post I like to discuss using SignalR as a surprisingly nice technique for common api-functionality. Yes, SignalR is not only very nice for duplex, multiuser communications. With it’s fallback support, automatic routing and javascript proxy to serverside methods I really think it’s a stable and easy to use technique also for regular ajax scenarios.

Here are the only steps you need to go through to get a simple api up with SignalR:

1. Reserve the path /SignalR/Hubs within Umbraco web.config umbracoReservedPaths.
2. Install-Package SignalR in your site
3. Create a Hub with some methods that you like to expose to the client side

public class OrderHub : Hub
{
  public Order Get(int id)
  {
    return WebApp.Db.SingleOrDefault<Order>(id);
  }
}

4. Reference the necessary javascripts on your page

<...jquery...>
<script type="text/javascript" src="/scripts/jquery.signalR-0.5.3.js"></script>
<script type="text/javascript" src="/signalr/hubs"></script>

5. Add signalr client scripts

// start the connection (it's extended from $)
$.connection.start()

// get something from the server, we can use our OrderHub method names (automatically camel cased), 
// use a callback to do something with the retrieved order
  $.connection.orderHub.get(orderId, 
    function(order){
      alert("Yay, order " + order.name + " from " + order.date);
    });
}

There you go, basic api-functionality with a few lines of code.

You can send jsons from client to server aswell, and get them as your own types (Poco’s) on the server side.

The /signalr/hubs path is a path to an automatically generated javascript file that creates a proxy to your server methods. Open up that path in your browser to check out the code.

And when you do need chat functionality, or you like to push information from server to client, thats also easily possible, just check out the numerous SignalR samples and the docs.

Pros

* Easy to setup and use, no need for web.config editing or adding routes
* The js proxy makes your javascript short and nice + it’s possible to explore the api with a javascript console, in Chrome and Firefox you even get intellisense for you callable server side methods.
* Push and duplex communication available when you need
* Falls back to IE6 iirc
* Cool library
* Great support and still under heavy development

Cons

* New and not that well tested, changes between each new version
* Requires Javascript on client
* No Rest (if that’s a requirement)
* Limited to 6 connections at a time (user cannot have more tab’s open in his/hers browser to your application)
* Can’t use Session in a hub (but that might be a Pro)

Some futher comments and observations

Its nice to have the hubs in a separate VS project “MyProject.SignalR” or “MyProject.Core”. When doing so the nuget to install in that core project would be SignalR.Server. And the full SignalR should be installed in the Umbraco web site project.

You can get current (logged in) username in a hub with the standard call to System.Web.Security.Membership.GetUser();

Hub’s are per request

No need to collect all functions in one Hub, use several Hubs to separate stuff

I don’t think you can use Umbraco context in a hub ootb. Will check that out futher on, my use case here was to build a BL api to be used in a Umbraco site, not to expose Umbraco functionality.

Two other blog posts that talks about using SignalR for regular ajax calls:

Clean up your MVC app with SignalR by Yngve Bakken Nilsen

Why should ASP.NET developers consider SignalR for ALL projects? by Kevin Griffin

A playful look at WebSockets – with the help of the XSockets library

Standard

What’s the best way to spend a friday night to saturday afternoon, in the city of Sundsvall, Sweden? What about coding some WebSockets together with others like minded (+ having one or two sponsored beers)? In the end of september team XSockets and XLent hosted such an event and I was happy to be able to join.

For me it was the first real experience of WebSockets coding, and in this blog post I’ll write a few words about it (so there – my usual “I’m a noob-disclaimer”).

WebSockets (and the WebSockets API) is currently in an evolving phase, and as such it has varying support in the different web browsers. It’s quite a lot of work to use it directly with cross-browser support for real time applications. Therefore many look for helping libraries, actively maintained by people following the ongoing development of WebSockets and with fallback support for non-websockets-supporting browsers. XSockets is such a library. It is under active development, has support for several WebSockets protocol versions and it has fallback support that works in most browsers, with the help of Flash or Silverlight plugins.

Setting up an XSockets Visual Studio solution is easy with the help of the XSockets Nuget package. The recommended way to start playing [link to video]see also this walkthrough is to 1) create an empty MVC3-application, then 2) type Install-package XSockets in the package manager. The Nuget installs a XSockets server project, a custom handler project, and a samples web project with a few samples. To have a go – 3) right click the server and run it. Then 4) open a Sample project html page also by right clicking, and browse open the file – preferrably in Chrome.

The parts of an XSockets solution

For a XSockets solution to run you will need the following.

  • A websockets server. A .Net Windows command line application or a service. Configured to serve websockets communication on a specified port (for example 4502). The easiest way to get a server up and running is simply by installing the Nuget (se above).
  • Client side code. For example js code using the jxsockets client side libray – best if they are running on WebSockets enabled browsers like Chrome, or Safari.

The clients all communicate with the server, there’s no direct peer-to-peer communication. However, the server can of course maintain a communication between two individual clients.

Here is an example of how an XSockets (and WebSockets) communication sequence can look like:

1. Client A creates a jXSockets instance, responsible to handle WebSockets communication with a running XSockets server.

var ws = jXSockets.xWebSocket('http://myserver.com:4502/XSockets.Core.Handlers.Generic, jXSockets.WEBSOCKET);

2. The server establishes and opens the connection and the event “open” is triggered. The client can now start listen to and trigger own events.

ws.bind("open", function() { $('#status').text('<p>Connection open</p>');} );

3. Client B does the same. Now the server has two open connections. Each client is represented by a guid on serverside, and messages (as events) can easily be sent to all clients or a selection of clients.

4. Client A triggers a “OnChatMessage” event with the data “Hello WebSockets” and “John Doe”.

// Create a WebSocketMessage 
var myMessage = new $$.WebSocketMessage("OnChatMessage");
myMessage.AddJson({Text: "Hello WebSockets",UserName:"John Doe");
//  Send the message using the .trigger(WebSocketMessage) method 
ws.trigger(myMessage.PayLoad());

5. The server’s generic event handler is configured to listen to all events and broadcasts the event directly to all other clients.

6. If Client B has a binding to the “OnChatMessage” event it will get the “Hello World!” data and can for example display it on a web page.

// Event handler for the WebSocket event named OnChatMessage, where the WebSocket instance is named ws
ws.bind("OnChatMessage",function(message) {
 $('#message').append('<p>' + message.Text + ' from ' + message.UserName + '</p>');
});

7. More messages is being sent between the clients and the server.

8. The connections stays open until they are actively closed. This means that the need for overhead is minimal, which in turn means it’s very efficient to send a lot of data back and forth compared to the traditional http request / response method which has a lot of overhead.

We can also bind to the close event if we like

ws.bind("close", function() { $('#status').text('<p>Connection closed</p>');} );

More server side

The generic handler is best for demo usage, and not really (?) meant for real applications. But it’s very easy to build a custom handler which can be setup to handle the communication however you like.

Hackaton

A really fun part – and the part that was given the most time – of the CodeCamp was where we participants was given the task to code real XSockets applications, which should be demo’ed at the end of the camp. It resulted in really cool apps, most of which had a entertainment/game theme, but there were also real business/industry ‘real-time-dashboard’ like applications.

Here’s a short video of my contribution.

In all, the CodeCamp proved to me that WebSockets is a technique that has an important place in the modern web, and XSockets is a well engineered and easy-to-use library for WebSockets solutions.

One file CRUD sample with NancyFx, SisoDb and HtmlFormHelper

Standard

Following my NancyFx & SisoDb experiments I’m adding some CRUD with the help of my HtmlFormHelper class. So, here’s a one file Nancy CRUD sample (well plus the .dll’s and HtmlFormHelper.cs).

Note : I’m still very new at NancyFx, and I’m doing this to learn myself, there’s better samples out there, showing how the gurus does stuff with Nancy. Have a look in the samples in the original Github repository. And theres also Nerd Beers by Tom Janssens. And Building a photoblog with Nancy by Kristof Claes

And be sure to read the Nancy official documentation

Demo

Code excerpts

The Poco, SisoDb will take care of it as is, no need to define a sql table or mapping:

public class Product
{
    public Guid SisoId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string SomeIgnoredProperty { get; set; }
}

The table template (using the Nancy built in Super simple view engine):

var tableTemplate = @"
    <table>
        <tr>
            <td>Name</td>
            <td>Description</td>
            <td colspan=""2"">&nbsp;</td>
        </tr>
        @Each.Products
            <tr>
                <td>@Current.Name</td>
                <td>@Current.Description</td>
                <td><a href=""/products/edit/@Current.SisoId"">Edit</a></td>
                <td><a href=""/products/delete/@Current.SisoId"">Delete</a></td>
            </tr>
        @EndEach
    </table>";

Defining the html form elements using HtmlFormHelper:

var productForm = new HtmlFormDescriptor("product-form");
productForm.Add("Name", required: true);
productForm.Add("Description");
productForm.Add("Submit", type:"submit");

Building the full page:

public string htmlPageView(string title, string htmlContent)
{
    var htmlPageTemplate = @"<html>
        <title>{title}</title>
        <body>
            {menu}
            <h1>{title}</h1>
            {content}
        </body>
        </html>";

    var htmlMenu = @"<ul class=""menu""><li><a href=""/products"">Products</a></li></ul>";

    var view = htmlPageTemplate
        .Replace("{title}", title)
        .Replace("{menu}", htmlMenu)
        .Replace("{content}", htmlContent);

    return view;
}

Nancy goodness in action:

Get["/"] = x =>
{
    string htmlInsertForm = "<h2>New product</h2>" + productForm.Html(action: "/products/insert");
    return htmlPageView("List products", htmlListProductNames() + htmlInsertForm);
};

Get["/edit/{id}"] = x =>
{
    Product product;
    string htmlEditForm = "";
    using (var uow = db.CreateUnitOfWork())
    {
        product = uow.GetById<Product>((System.Guid)x.id);
        htmlEditForm = productForm.Html(product);
    }
    return htmlPageView("Edit product", htmlEditForm);
};

Get["/delete/{id}"] = x =>
{
    string htmlDeleteResult = "";
    using (var uow = db.CreateUnitOfWork())
    {
        uow.DeleteById<Product>((System.Guid)x.id);
        uow.Commit();
        htmlDeleteResult += "<p>Successfully deleted the product</p>";
    }
    return htmlPageView("Delete product", htmlDeleteResult);
};

Post["/edit/{id}"] = x =>
{
    var htmlEditResult = "";
    Product product;
    using (var uow = db.CreateUnitOfWork())
    {
        product = uow.GetById<Product>((System.Guid)x.id);
    }

    // Update model and validate
    var validationResult = (HtmlFormDescriptor.ValidationResult)n.TryUpdateModel<Product>(Request.Form, ref product);

    if (validationResult.IsValid)
    {
        htmlEditResult = "<h1>Valid</h1>";
        using (var uow = db.CreateUnitOfWork())
        {
            uow.Update<Product>(product);
            uow.Commit();
            htmlEditResult += "<p>Updated product id " + product.SisoId.ToString() + "</p>";
        }
    }
    else
    {
        htmlEditResult = "<h1>Something is not valid</h1>";
        htmlEditResult += productForm.Html(product);
    }
    return htmlPageView("Edit product", htmlEditResult);
};

Full source

HtmlFormHelper Gist

Edit : Client side validation

I made some changes to be able to easier include the HtmlFormHelper client side validation script + add scripts and css’es in general:

public string htmlPageView(string title, string htmlContent)
{
string htmlPageTemplate = @"<html><head>
    <title>{title}</title>
    {css}
    {scripts}
</head>
<body>
    {menu}
    <h1>{title}</h1>
    {content}
</body>
</html>";

    string htmlMenu = @"<ul class=""menu""><li><a href=""/products"">Products</a></li></ul>";

    string htmlCss = @"<style type=""text/css"">
    div.labelinput, div.submit {clear:both;}
    .labelinput label {width:100px;display:block;float:left;}
    .labelinput input {width:200px;display:block;float:left;}
</style>";

    string htmlScripts = @"<script type=""text/javascript"" src=""http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.2.min.js""></script>
<script type=""text/javascript"" src=""http://ajax.aspnetcdn.com/ajax/jquery.validate/1.8/jquery.validate.min.js""></script>";

    var view = htmlPageTemplate
        .Replace("{title}", title)
        .Replace("{menu}", htmlMenu)
        .Replace("{css}", htmlCss)
        .Replace("{scripts}", htmlScripts)
        .Replace("{content}", htmlContent);

    return view;

}

Now all I have to do to create a form that has client side validation is:

var productForm = new HtmlFormDescriptor("product-form", includeClientSideScript: true);

The Nancy google group

The NancyFx google group is a great place to find q’s and a’s for how to use the framework. If you have a question – put it there – and you’ll likely get an answer by the Nancy gurus, Andreas Håkansson, Steven Robbins et al before you know it. They simply rock!

No fuzz adding properties

Oh, forgot to mention: to add another property, and storing it in the database is as easy as adding it to the Poco and the html form definition, just like I did with ArticleNumber here:

public class Product
{
    public Guid SisoId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string ArticleNumber { get; set; }
    public string SomeIgnoredProperty { get; set; }
}

 

var productForm = new HtmlFormDescriptor("product-form");
productForm.Add("Name", required: true);
productForm.Add("Description");
productForm.Add("ArticleNumber", required: true);
productForm.Add("Submit", type:"submit");


There’s some “code first” for us (or rather code only), gotta love SisoDb!

A one file Asp Net web application with NancyFx and SisoDb

Standard

It’s hard to see how an Asp Net webapp with database functionality can be easier/less ceremony than with the help of NancyFx + SisoDb. The sample I’m going to show here is very far from a full real web application, it’s rather trying to show one way of creating the most basic building blocks of such an app.

Followup article : one file full CRUD sample.

To join my sample here start by creating an empty Asp Net web application within Visual Studio. And then add the two packages Nancy.Hosting.Aspnet and SisoDb. Just as easy as opening Tools > Library Package Manager > Package Manager Console. And then run the two install commands:

install-package Nancy.Hosting.Aspnet
install-package SisoDb

Nancy

A basic Nancy app can be setup with just one cs-file (a NancyModule class):

public class NancyStart : Nancy.NancyModule
public NancyStart()
{
    // Todo: Initialize db
    Get["/products"] = x =>
    {
       return "<h1>my products</h1>";
    };
}

The Nancy Nuget gave you a ootb basic routing configured in your web.config. So with the code above you should be able to browse to /products and get the h1.

With a small change we get the idea of how we’re going to get the actual products:

Get["/products"] = x =>
{
    return htmlForm + htmlListProductNames();
};

And a post:

Post["/products"] = x =>
{
    var htmlResult = InsertProduct(Request.Form["name"]);
    return htmlResult + htmlForm + htmlListProductNames();
};

The htmlForm and htmlListProductNames are just strings with html tags:

string htmlForm = @"
    <form method=""Post"">
        <input type=""text"" name=""name"" id=""name""/>
        <input type=""submit""/>
    </form><br/>
";

SisoDb

To handle the db as easy as possible SisoDb is a neat alternative. It’s storing regular poco’s as json objects in a regular sql database, which means there’s no need for setting up sql schemas for your pocos.

Here’s my Product class:

public class Product
{
    public Guid SisoId { get; set; }
    public string Name { get; set; }
    public Product(string name)
    {
        this.Name = name;
    }
}

And here’s how to store a product into the DB:

public static void InsertProduct(string name)
{
    using (var uow = db.CreateUnitOfWork())
    {
        var p = new Product(name);
        uow.Insert(p);
        uow.Commit();
    }
}

The first time you’re saving a product SisoDb will create necessary db schemas automatically.

To get a list with all products, and return a basic html list, we can do:

string htmlListProductNames()
{
    IEnumerable<Product> products;
    var retval = "";
    using (var uow = db.CreateUnitOfWork())
    {
        products = uow.GetAll<Product>();
        retval = "<ul>";
        foreach (var p in products)
        {
            retval += "<li>" + p.Name + "</li>\n";
        }
        retval += "</ul>";
    }
    return retval;
}

The full source for my noob app can be found at gisthub. Comments are more than welcome. I’m a 100% Nancy and SisoDb noob and there’s probably many things that could be made better.

View Engines

There’s quite a few ViewEngines avaliable for NancyFx, there’s for example Spark, NDjango and Razor. All requires the install of an additional dll (via a Nuget of course – I’m starting to get very lazy about dll’s, if they aren’t nugetted I probably wont use them…). When I was browsing for the Razor dll I found out there’s indeed an included view engine in Nancy – the Super Simple View Engine. For the purpose of this sample that view engine is good enough:

string htmlListProductNames()
{
IEnumerable<Product> products;
var retval = "";

using (var uow = db.CreateUnitOfWork())
{
    products = uow.GetAll<Product>();
    dynamic model = new System.Dynamic.ExpandoObject();
    model.Products = products;

    var template = @"
<ul>
@Each.Products
<li>@Current.Name</li>
@EndEach
</ul>
";
    // declared in the function for brievity
    var viewEngine = new Nancy.ViewEngines.SuperSimpleViewEngine viewEngine()
    retval = viewEngine.Render(template, model);
}

return retval;
}

WebMatrix?

Using WebMatrix its also very easy to get started with NancyFx. You just need to add the Nuget and start coding. Have a look:

Two notes here : I’m creating a temporary dummy foo.cshtml to be able to start my site in a browser. To be able to go to the /_Admin/ page from where the Nugets can be installed. Also I’m storing the NancyStart.cs file in App_Code, which means I can edit it more on the fly than if I had it in a precompiled .cs.

Ref :
Introducting Nancy (Elegant Code)
Nancy Fx @ GitHub
SisoDb – a Simple-Structure-Oriented-Db

A very nice NancyFx introduction : Building a photoblog with NancyFX and Simple.Data Part 1: Setting up the project

Hope you liked the post. Happy coding!