Advertisements
//
archives

Archive for

A .NET Developer’s Introduction to node.js – Part 1

Nearly my entire professional career has been devoted to developing on Windows platforms, specifically the .NET framework. But every developer needs to stand up and stretch once in a while and expand their body of knowledge to stay current and limber. Lately, one of the hotspots in the software scene has been node.js, a JavaScript based system for creating highly scalable internet applications. This is the story of a C# .NET developer learning node.js to do something useful.

A took a brief look last night and I’m going to try to use node.js to update my FitBit weight statistics. Node.js is just JavaScript and therefore is not that big of a strech (since I use JavaScript everyday in my job), and that’s a good thing. It gives me some room to grow without going too far out there.

Installing node.js

A Bing search for node.js brought me to nodejs.org where I clicked “Download” and then, since I’m on Windows 7, I clicked “Windows Installer”. The installation was as easy as it gets. There are no options. Just run the .msi and away it goes. At the end of the installation, it says to open a command prompt and type node to get started. I did this and this is what I got:

Great! Now what? Off to nodejs.org to read the documentation.

Someday We’ll All Say ‘Goodbye World’

I knocked out the standard HelloWorld example put forth by the documentation on their synopsis page:

var http =  require('http');

http.createServer(function (request, response) {  response.writeHead(200, {'Content-Type': 'text/plain'});  response.end('Hello World'); }).listen(8124);

console.log('Server running at http://127.0.0.1:8124');

After opening my web browser, I pointed it to http://127.0.0.1:8124, and sure enough, there on the screen are….those words.

Now what? More documentation? Pfft. No. Lets just start writing code and see what happens. It’s on to the npm registry to find some existing code to connect to FitBit. Npm is a package manager for node and it’s the easiest way to get different modules required by your software onto your machine. In .NET speak, think of it as NuGet and a way to get all those external references into your project. I searched for FitBit and find fitbit-js over on GitHub.

Over on the GitHub page, the README says to install it like this:

npm install fitbit-js

And here’s what I got:


Giant fail.

I wasn’t really surprised because on the npm page, fitbit-js was listed as good for node.js version >= 0.2 and < 0.5. Since I had just installed node, the version I have is 0.6.13. So, it looks like the package manager is keeping me from installing it that way. That’s probably good, but a little annoying.

Next, I tried just copying the fitbit_client.js file into the node/node_modules/npm/lib folder.

Then, using the example from the fitbit-js project, I try to see if it works as is.  Nope. Or rather, the test is looking for a module called ‘express’. But I don’t see that anywhere. So time to start looking around. A hint on stackoverflow lets me know that I need to install express via the npm. I did, and, voila, I now had express. (Note, the Appendix 1 of the node.js documentation  suggested a few useful packages that are often used). Let’s try the client again.

Now it can’t find connect. Okay. Npm to rescue again. That works, but I do get a warning — something about node 0.5 again.

Hmm. We’ll see if this works anyways.

At this point, I got a little stuck as the syntax for loading up the fitbit_client module was a little unfamiliar. Rather than digging too deep into it (that’s for another time), I instead decided to fork the repository from GitHub and see if that worked.

I edited the package.json to allow me to remove the < 0.5 version limitation and try ‘npm install’ in the fitbit-js folder. That works. I edit the test.js file in the example folder to include my secret key for my fitbit stuff. However, at this point, there is a slight bug in the fitbit-js example.

Keeping Up With the Nodes

The version of the test.js I forked had the following line of code in the setup:

app = express.createServer(connect.bodyParser(),                            
                           connect.cookieParser(),
                           connect.session({secret: 'session'}));

However, when we try to hit the page, this is the error we get:

Error: connect.cookieParser("secret") required for security when using sessions

I’m fairly confident that the original author didn’t post broken code, so I’m assuming that something must have changed in the post 0.5 version timeframe. I just changed the above line to:

app = express.createServer(connect.bodyParser(),
                           connect.cookieParser('session'),
                           connect.session());

I retried the url and was redirected to the FitBit oAuth page asking me to authorize my account to my app. Now we’re talkin! I agreed and got a PIN number to put back into the node.js app. What? It was supposed to redirect me back to the app I used and go from there!

It turns out, I was missing something in the FitBit application setup. I needed to tell FitBit that my application was a browser based app, and I gave it my callback url for it to call me back. Once that was done, I was given the display URL which I clicked on and was able to retrieve some JSON.

Fork and Pull

I had forked the fitbit-js repository, so I committed my changes to make it work with node.js 0.6.13 and pushed them back up to GitHub and submitted a pull request. This sample doesn’t really do much right now; it only retrieves my FitBit activity for a specific date. In the next entry, we’ll work on putting some data into FitBit.

Advertisements

Announcing – St. Patrick’s Photo Booth for Windows Phone

Just in time for St. Patrick’s Day on Saturday, I’d like to announce the release of St. Patrick’s Photo Booth on the Windows Phone Marketplace. Similar to the highly popular North Pole Photo Booth, this springtime version features St. Patrick’s Day and other Irish themed props. It uses the same face detection to automatically place a hat on your photo which you can easily swap out for others. Zoom, rotate, flip, lock, and delete props with simple finger gestures.

Speech Bubbles

New for this version is the addition of editable speech and thought bubbles. Just drop one onto your photo, double-click on it, then use the on-screen keyboard to write something clever.

Collaboration

This time around, I collaborated with Justin from Adkins Software Development on some new features such as integration into the photo hub and enabling a trial mode. Expect to see more in the future from this collaboration. Check out his app, WP7 Tracker, in the Marketplace.

So go check it out! It’s a fun app for a night of green beer and jig dancing!

Integration Test ASP.NET Web API with StructureMap

One of the best new features of ASP.NET Web API is the ability to self host. This means that inside of our integration test, we can create a web server in memory, work with the web server through a web client (in memory as well), and not have IIS running on the box or on some other server to test. It’s all done “in-house”.

I’m using Nunit for testing and StructureMap for Inversion of Control (IOC).  I’ve got two projects. The first is a MVC 4 Application with a Web API ApiController. The second project is a standard test project with Nunit. I’m on Visual Studio 11 on Windows 7. Let’s dig in. First, the controller I’m trying to integration test:

public class DrinkLogsController : ApiController
{
	private readonly IDrinkTrackerContext _context;

	public DrinkLogsController(IDrinkTrackerContext context)
	{
		_context = context;
	}

	[ValidationActionFilter]
	public HttpResponseMessage PostDrinkLog(DrinkLog value)
	{
		.
		.
		.
		// Code for the post handler goes here. It's not relevant to the discussion at hand.

	}

}

So what do we have? A typical ApiController for a entity called DrinkLogs. This controller is taking in an IDrinkTrackerContext which in reality is actually an instance of a DbContext. But since we’re using IoC and interfaces, the controller doesn’t really know much about the implementation of what we’ve passed in. No tight coupling here! There’s a POST handler that’s taking in a new DrinkLog and doing something with. We don’t care what it’s doing really. At least not for the purposes of this blog entry. Now let’s look at the test harness.

using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web.Http;
using System.Web.Http.SelfHost;
using DrinkTracker.Core.Model;
using DrinkTracker.WebAPI;
using DrinkTracker.WebAPI.Controllers;
using DrinkTracker.WebAPI.Filters;
using NUnit.Framework;
using Newtonsoft.Json;

namespace DrinkTracker.Test

{
	[TestFixture]
	public class DrinkLogApiIntegrationTest
	{

		[Test]
		public void Post_Drink_Log_With_No_Drink_Failure()
		{
			var baseAddress = "http://localhost:8080/";

			var selfHostConfig = new HttpSelfHostConfiguration(baseAddress);

			selfHostConfig.Filters.Add(new ValidationActionFilter());
			selfHostConfig.Routes.MapHttpRoute(
			    name: "DefaultApi",
			    routeTemplate: "api/{controller}/{id}",
			    defaults: new { id = RouteParameter.Optional }
			);

			selfHostConfig.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;

			var container = IoC.Initialize();
			var resolver = new SmDependencyResolver(container);

			selfHostConfig.ServiceResolver.SetResolver(resolver.GetService, resolver.GetServices);

			var server = new HttpSelfHostServer(selfHostConfig);
			var client = new HttpClient();
			server.OpenAsync().Wait();

			client.BaseAddress = new Uri(baseAddress);

			var newLog = new DrinkLog { PersonId = 1, LogDate = DateTime.UtcNow };

			var postData = new StringContent(JsonConvert.SerializeObject(newLog), Encoding.UTF8, "application/json");

			var r = client.PostAsync("api/drinklogs", postData);

			Assert.That(r.Result.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));

		}

	}
}

Before I get too far explaining this test, it’s imperative to note that in order to use self hosting, you need to setup an http url namespace resolution. This is described in detail over on the Asp.Net website. Go read that, do what it says, and come back.

Too lazy to go check it out? Here’s what it says: you need to open up a developer command prompt and execute the following command (with elevated privledges):

netsh http add urlacl url=http://+:8080/ user=machine\username

Now let’s look at the test code. Right off the bat we’re setting up a location for the server to listen at. Then, using that address, we can create a HttpSelfHostConfiguration. This is where we’ll put all the secret sauce. You’ll need to do all your MVC setup work that would normally be done in the Global.asax or in the App_Start folders (where StructureMap for MVC is setup) of your MVC project. Easy enough to just go look at your MVC project and see what you’re setting up. In my case, I’m registering an ActionFilter and a Route. Set this here because the Global.asax is part of the ASP.NET runtime which we’re not really going through. I also set the IncludeErrorDetailPolicy to always to make sure I get back detailed information about any problems.

Now we move on to the IoC. Like I said, I’m using StructureMap because that’s what I’ve been using for MVC for a couple years. You could use your own flavor of IoC such as Ninject or Unity, but what’s important in this code snippet is that you get a reference to an IDependencyResolver.

Lets assume that I’ve got StructureMap setup as I want it inside the MVC project. In this case, calling IoC.Initialize() will setup StructureMap just as its setup in the MVC project. The SmDependencyResolver gives an IDependencyResolver we so longingly need which we then use to set the ServiceResolver on the HttpSelfHostConfiguration.

The hard part is done now. It’s all smooth sailing from here on out. We setup the HttpSelfHostServer passing it the configuration we so lovingly crafted earlier. Use server.OpenAsync().Wait() to put the server into a zen state of acceptance of all connections on the address we specified earlier.

Then it’s just standard HttpClient stuff. In this case, passing in a JSON representation of the new DrinkLog. Since this test is specifically testing to make sure that if the caller forgets a piece of data on a POST, we return a BadRequest HttpStatusCode. Once that’s tested, we’re golden. Or, more appropriately, all green.

If your Result.StatusCode is 500, Internal Server Error, check the error detail. If you see an error like “No parameterless constructor defined for this object.”, then your IoC isn’t setup correctly. Set a breakpoint in your constructor to confirm to yourself that you’re not setup correctly. This is ususally caused by not telling the IoC system about your bindings. Fix that, try again. If it still doesn’t work, ask a question.

Happy Web APIing.

United Pixelworkers T-Shirts for February-March 2012

Man, these United Pixelworkers folks are killing it lately. Last month they released a new version of their web site and it. is. awesome. Unfortunately for me, I totally missed the sale last month. But not this month. This month they had 15 different shirts up for sale. I think I’m still partial to the idea of guest designers and so I’m drawn to that over the the different region ones the have up. I picked up the “alignment” one by Evan Stremke.

You’ve got until Monday to get in on this month, so move yourself over to unitedpixelworkers.com to get your own t-shirt ordered.

PLUS: Don’t forget to check out my t-shirt at tshirtheavy.com.  

Advertisements

I'm Ken Stone. I'm an indie developer with a focus on .NET and Windows Phone development. I have a day job, but everything I say is mine alone.

TechEd 2012July 11th, 2012
Let the learning begin.