Latest Tweet:
  • Loading...

Introduction

I have previously blogged about the Silverlight testing framework that was originally released as part of the Silverlight 2 Beta 1 control source. Jeff Willcox, the lead developer on the framework, recently announced an updated version of the framework for the Silverlight 2 Release Candidate. The updated version contains several interesting new features, which Jeff has covered in a great thorough blog post. I’m not going to re-iterate the feature list in this post, but rather focus on the one of the new features; tagging of tests.

Types of automated testing

Automated unit testing of code has become a common development practice, and as developers we have a wide variety of frameworks to pick from to help us do testing. A common misperception is that any test written using a testing framework is a unit test. That is not necessary true as there are multiple other types of test you can write for your code. Phil Haack, one of the program managers on ASP.NET MVC, wrote about the boundaries of unit tests on his blog a few months back. I recommend this post as a good overview of some of the considerations you should make when writing unit tests.

I’m quickly going to list the types of tests I normally write when building Silverlight applications.

  • Unit Test
    Tests a single unit of work. In most cases a single method in a single class. Normally don’t touch the database, the file system or the network. Should execute quickly with no side effects (changed global state).
  • Integration Test
    Tests how multiple classes integrate with each-other, or how a class integrates with the environment. I.e. parsing of an XML file, reading/writing to a database, or accessing data on the network.

  • Smoke Test
    Simulates an user interacting with the application. Tests multiple classes and can cross boundaries such as network, file system or database. In many cases you write your smoke tests by automating the user interface.

Even if your tests aren’t a true unit tests according to the list above, it’s perfectly fine to use a testing framework like nUnit to write your integration- or smoke tests. There are other types of tests as well, i.e. performance tests, stress tests and acceptance tests. For these types of tests you often use different tools or extensions to your testing framework.

One of the considerations you should make when writing your tests is to keep your unit, integration and smoke tests separated. You should try to keep your unit test running as quickly as possible, something that is easier to achieve if you focus on not crossing any process boundaries. If testing becomes slow and tedious developers might start cheating and not run the test suite as they change code. One way to separate your tests is to have different projects for each type of tests. This is a good solution in many cases, but for smaller projects (like all of my Silverlight demo applications) this may lead to a cluttered project structure. In the Silverlight testing framework you can organize your tests in a different way by adding tags to test classes and test methods.

Tagging tests

One of the new features that were introduced in the latest version of the Silverlight Testing Framework is support for tags. You can apply multiple Tag-attributes to any test class or method in your test suite. The Tag-attribute takes accepts a string, so it is up to you to decide how to organize your tests. As an example for this post I am going use the YouCard application I built for REMIX. The tags I am going to apply are based on the types of tests I listed above; Unit, Integration and Smoke. The YouCard test suite isn’t too big and only got 13 tests in it. But it got a little bit of everything, so it should be a good example.

The most obvious candidate for being tagged as a unit test is the value converters tests. A value is like a mini-adapter you can apply during data binding to convert from one value to another. It got two simple methods, Convert and ConvertBack, and no external dependencies.

Test tagged as unit test

The YouCard application uses the Model-View-ViewModel pattern, so the next set of tests to be tagged as a unit test is the ViewModel tests. The ViewModel class has two dependencies to a Flickr service and a Twitter service. Because these dependencies are implemented as interfaces and injected in the ViewModel constructor I can supply test mocks, making this a pure unit test and not an integration test.

Now that we’ve identified some unit tests it’s time to show some examples of integration tests. The two most obvious candidates are the classes responsible for accessing the Twitter and Flickr APIs. Both implementations are based on an interface, making it easy to mock the dependency when testing the ViewModel. However, we still want to write tests to verify that the code downloading and parsing the XML from Twitter and Flickr works as expected. This means accessing the network, and thus crossing the boundaries of what we consider a unit test.

Test tagged as integration test

The final type of test we want to identify and tag is a smoke test. The Silverlight Testing Framework runs inside the browser with full access to the Silverlight runtime, making it easy to write user interface tests. The YouCard test suite has one smoke test simulating a user entering Twitter usernames into the textbox and hitting the add-user button. The test waits about a second between each user interaction, and it uses real implementations of both the Twitter and Flickr interfaces. This makes the test fairly slow to execute, but still valuable as it gives us a verification that the application works as a whole when all the pieces are coupled together.

Executing tests based on tags

Now that the tests are categorized using tags, how do we execute specific tests based on the tags? In the Silverlight Testing Framework you create the test page in the Application Startup event in the application class. In CreateTestPage method accepts a UnitTestSettings object you can use to configure the test framework. One of the properties on the settings object is a TagExpression property. The name of the property hints that we can supply more than the name of a simple tag. Jeff hasn’t documented this feature yet, so I don’t know the limits of the expressions you can create. You can do things like “!Unit” to execute all tests except the once tagged as “Unit”. I don’t know if you can use more complex expressions and combinations of tags. But in most cases supplying a single tag should be enough.

Configuring test framework in Application Startup

Since configuration of the test framework is done through code it’s easy to make the tag expression dynamic. The example code looks for an initialization parameter called tag, and if found its value is applied as the tag expression. Initialization parameters are passed in when the Silverlight object is created in on the page. If you are using HTML to create the object you add the initialization parameters as a param-element to the object-tag. If you use the ASP.NET Silverlight server control you set the InitParameters property. In this example I have a Silverlight and some ASP.NET code to check the query string. If the query string contains a tag-element the value is passed to the Silverlight control as an initialization parameter. Using this technique you can simply change the URL to execute your test suite with different tag expressions applied.

Passing a tag from the query string to the init parameter.

To execute the code simply navigate to the page hosting the Silverlight tests. By default it will execute all tests, but if you add a tag-parameter in the query string you can control which tests to execute.

Executing tagged Silverlight tests.

Summary

The updated version of the Silverlight Testing Frameworks got lots of new useful features. Support for tagging is one of them. Hopefully this post gives you an introduction to how you can use tags to organize your tests. The deployed version of the DiveLog and YouCard application use this technique, and if you want to see how the test framework executes tests just click one of the links below.

The most current developer build of the Google Chrome browser has fixes for some of the initial Silverlight problems reported when the beta was made available. The beta did load the Silverlight plug-in, but people experienced several bugs. On the sites I tried Chrome would render the application, but any interaction from keyboard or mouse wouldn’t get passed to the application. This is now fixed and Chrome now runs all the Silverlight 2 applications I’ve tried without any problem. I’ve tested it with the sample applications I’ve built (YouCard and DiveLog); as well as with some of the larger reference applications such as Hard Rock Memorabilia and the Microsoft Health CUI demo application. All of them work just fine. Even things like the browser navigation integration in the Dive Log application works as expected.

One of the cool things Google have done with Chrome is to make it really easy to run early developer builds. This 7-step tutorial explains how to enable what Google calls the Developer Channel. What this does is that Chrome will now check a different repository for updates and new releases than people using the Beta Channel (default). After running a tool that enables the Developer Channel you get fresh builds through the automatic update system (the about dialog).

This is great news for the Silverlight community as this clearly indicates that Chrome will have full Silverlight support when it comes out of beta. I've included some screenshots of Silverlight applications running in Chrome. If you want to stay on top of current builds of Google Chrome I also recommend following the Twitter user @GetGoogleChrome.

Update

YouCard running in Google Chrome YouCardSiteSpesificBrowser Dive Log running in Google Chrome Microsoft Health CUI running in Google Chrome Hard Rock Memorobilia running in Google Chrome

On the Silverlight.net forums there are several questions about how to configure Silverlight applications. A common question is how to change the URL of a WCF service you are consuming. Another common question is how pass in some user defined configuration settings. There are several interesting solutions, and a couple of days ago Bill Reiss posted an article about “Calling WCF on the server of origin from Silverlight”. Bills solution involves using the HTML Bridge to grab the current URI, and building up the URL of the web service, and then creating the service client using one of the constructors allowing you to manually specify binding and endpoint. This is all cool and really helpful in many cases, but the ServiceReferences.ClientConfig file is there for a reason. I think a lot of developers are a bit confused about how to use this file. And I don’t blame them. In Silverlight 2 Beta 1 this file was generated by Visual Studio, but was not read by the WCF runtime. In Beta 2 this was fixed, and the WCF runtime will now read and use the configuration file.

A lot of developers are afraid they have to rebuild their application to change web service configurations; something Bill also write in his blog post:

This is fine if you're hitting a service like Digg or one of the other public web service APIs out there, but not if you want to be able to test on your own machine and also deploy the same XAP to your server without rebuilding.

You could go ahead and change this to the URI on your server and rebuild, but then it won't work locally for testing unless you have a crossdomain file on your server, and you would be hitting your server's web service, not your local one while testing.

When building a Silverlight 2 application Visual Studio 2008 will spit out a XAP file in the Client Bin directory. The XAP file is just a standard ZIP archive containing some assemblies, the configuration file, a manifest file, and any resources you might have added to your project and market as content. It’s completely safe to rename it to ZIP, unpack it, make changes to the ServiceReference.ClientConfig file and package it all back together to a XAP file. Turns out repacking your XAP file is actually a good idea. Back in May Valeri Hristov discovered that he could chop 1MB of a 3MB large Telerik example application by repackaging it using the 7Zip application. Later David Anson followed up with some more examples showing a 22% average saving by repacking the XAP file… Why Microsoft is using such an inefficient ZIP implementation I don’t know –hopefully this will be fixed before release. Until then creating a post-build event that repackages your XAP will probably be the easiest 22% savings you will get all day.

Content of a XAP file

Anyway, let’s get back to configuration. Now that we can reconfigure our Silverlight application without rebuilding it we might be able to use the configuration file for more useful stuff. Silverlight does not come with a full configuration API like the full .NET framework. You do have the System.Configuration namespace, but it only contains some internal, abstract classes used by the Silverlight WCF stack. If you search for “configuration” in Reflector targeting Silverlight 2.0 you get some hits in the System.ServiceModel.Configuration namespace as well. It got configuration section handlers used by WCF to read information about your web service bindings and end points. All classes are internal and not really helpful for handling general application configuration.

Since the ServiceReference.ClientConfig is a plain XML file there is nothing stopping us from adding our own elements to the file. I decided to use the application setting convention we’re used to from .NET, and added an appSettings element with a bunch of key-value pairs elements. The application continued to run just fine with these additional elements. I also tried adding and removing service references from Visual Studio to see if it would screw up my changes. Thankfully Visual Studio only touched the serviceModel element, and didn’t care about our appSettings element. The ServiceReference.ClientConfig file now looks something like this:

configsample1

This is quite handy, as we can keep all application settings in one file using a format developers know. Next step is writing some code to read the configuration file. I decided to mimic how things work in the full .NET framework by creating a ConfigurationManager class with an AppSettings property. To parse the configuration file I used LINQ to XML which made it really easy to extract the key-value pairs.

configsample2

In the full framework the AppSettings property is of type NameValueCollection. This collection does not exist in Silverlight, so instead of re-implemented it I created a simple class backed by dictionary, exposed as an index property.

configsample3 

You read the application settings the same way you are used to from any .NET application:

configsample4

Hopefully this post gives you a better understanding how Silverlight 2 applications are packaged, and how to configure your application without rebuilding it. If I was consuming WCF services in my project I would add configuration management to my automated build process. It would be fairly simple to write a build script that repackages the XAP with a more efficient ZIP implementation, as well as building different versions for test, staging and deployment.

In an earlier post this week I wrote about implementing the Model-View-ViewModel pattern in the YouCard application. In this post I’m going to build on that and implement Inversion of Control Containers and the Dependency Injection pattern. Lots have been written about dependency injection, so the focus of this post will be on using dependency injection in a Silverlight context, and specifically how to implement it using the Ninject framework. For an excellent introduction to the pattern I strongly recommend Fowlers essay on the topic.

When getting into dependency injection you might get intimidated by the number of frameworks available to help you implement the pattern. It might give you the impression that dependency injection is something big and complicated, which is going to have a huge impact on how you build your software. The later might be true, but not necessary because of the framework but rather by the flexibility gained by introducing this pattern. In its simplest form dependency injection is about how you supply external dependencies to your application classes. In the previous blog post I refactored the Twitter and Flickr integration into external classes that complies with an interface. Depending on if the code was executed inside Blend or the browser I either use the real implementation, or a mock implementation providing some dummy data at design time.

Code sample 1

The problem with the above code is the coupling between the YouCardData class and the four classes implementing the IMicroBlog and IPhotoService interfaces. This high level of coupling between the view-model (YouCardData) and its external dependencies (Twitter and Flickr) makes the code less flexible. Coding against interfaces enables me to implement other services, such as a Picasa photo service, or a Tumblr micro blog service. The problem is how I get the YouCardData class to use these alternative implementations. The code is also hard to unit test as I can’t provide a mock implementation of the external services. We could refactor our code to take the external dependencies as constructor parameters like this:

Code sample 2

By doing this we allow the consumer of the YouCardData class to inject the external dependencies through the constructor. And in essence this is constructor based dependency injection, by hand. The above change gives us greater flexibility to provide alternative implementations of the services, either for testing purposes, or to provide new functionality. But there is still a problem with the code. If you want to create an instance of the class from XAML, for instance when setting the data context, a default parameter less constructor will be used. You could solve this limitation by adding an additional constructor like this:

Code sample 3 

This would solve the XAML problem, as any instance crated declaratively would use the Twitter and Flickr implementation, but for testing purposes we could provide our own mock implementation. But the solution still isn’t perfect. In the first constructor we had code to check if the class was consumed inside Blend or not. Depending on this we used different implementations of the external services. We could have kept this constructor, but instead we’re going to use an Inversion of Control container to help us build our objects.

Ninject

Lately I’ve been doing some research on UI frameworks and patterns, and many of these use some sort of dependency injection framework. The Prism-AG framework, a Silverlight port of the Composite WPF framework, uses a small dependency injection framework called DLLite. Another dependency injection ported to Silverlight is Unity, another framework from the Microsoft patterns and practices group. But my personal favorite so far is Ninject, the ninja of dependency injection. This framework caught my attention after listening to Nate Kohari in episode 5 and 6 of the AltDotNet podcast. Ninject describes itself the following way:

Ninject is a lightning-fast, ultra-lightweight dependency injector for .NET applications. It helps you split your application into a collection of loosely-coupled, highly-cohesive pieces, and then glue them back together in a flexible manner. By using Ninject to support your software's architecture, your code will become easier to write, reuse, test, and modify.

You shall feel my wrath as I rip you apart to inject my powers into you!

The footprint of the compiled framework is only 110KB, and you only need a single reference to Ninject.Core.dll too getting what you need in most scenarios. Strength of Ninject is the focus of configuration through code instead of XML. Most other IoC containers have a strong emphasis on XML based configuration of object dependencies. This has its advantages if your deployment environment varies a lot between installations, but in many cases this adds additional configuration pain.

  1. Your configuration can get more complex and verbose since you often have to write out fully qualified assembly names for each type.
  2. Its easer to break the application through simple typing mistakes.
  3. If the rules describing how to write your application together gets complex this might be hard to express through XML.

In comparison, Ninject uses a fluent interface, or sometimes referred to as "embedded domain-specific language". This lets you take advantage of the programming language to build up the wiring of your application. You can express complex rules of how the wiring should happen, and there is nothing stopping you from writing code that reads a configuration file if some of the wiring depends on user configuration.

"… There are cases where it’s easier to use program code to do the assembly. One case is where you have a simple application that’s not got a lot of deployment variation. In this case a bit of code can be clearer than separate XML file.

A contrasting case is where the assembly is quite complex, involving conditional steps. Once you start getting close to programming language then XML starts breaking down and it’s better to use a real language that has all the syntax to write a clear program.

…My advice here is to always provide a way to do all configurations easily with a programmatic interface, and then treat separate configuration file as an optional feature. – Martin Fowler"

Another cool aspect of Ninject is that it support Silverlight “out of the box”, and is not a port or a trimmed down version of a larger framework. Ninject was small to begin with.

Dependency Injection with Ninject

Adding Ninject support is fairly straight forward. The first thing we need to do is add is marking all constructors that take the dependencies, and mark it with a simple attribute.

Code sample 4

We also want to inject a persistence service into the main page view-model, the one controlling all the cards on screen. The persistence service is used to store all the users added, so that we don’t have to add them again when we come back to the application.

Code sample 5

If we use the Twitter service implementation we also want to inject a proxy URL. This is because Twitter doesn’t allow cross-domain callers and we need to proxy the request through our own server.

Code sample 6

The next thing we need to do is to wire the view-models to the services they need. In many IoC containers this is done through XML configuration, but in Ninject this is done through code and a fluent interfaces. Ninject uses a concept of modules to wire things together. One kernel (the container) can host multiple modules. For the YouCard application we need only one module.

Code sample 7

The benefit of fluent interfaces is increased readability of the code, so I’m not going to spend too much time describing the class line by line. The class derives from StandardModule, and overrides the Load method. In the Load method we set up the binding between the services and the concrete types. If you read the binding as “English”, from left to right, the binding rules should be fairly straight forward. Also worth notice is how I take advantage of configuration through code when I decide which implementation to use when the code is running inside Blend. I add a condition saying that the Twitter service should be used when executing inside the browser, while the mock service should be used from Blend.

To use the module I simply have to create a Ninject Kernel and pass it the module.

Code sample 8 

Notice how I don’t have to worry about constructing the YouCardData object. The kernel takes care of instantiating the object, and injects any dependency based on the bindings configured in the YouCardModule.

Data binding to objects built by Ninject

Now that we have configured our Ninject kernel the next challenge is getting our view-model objects out of the kernel and into the views, without breaking the design time experience in Blend. Setting the data context through code would be fairly simple. We could create the kernel in the application class, and then get it doing something like this.

Code sample 9 

That would enable us to have one kernel for the application (something you typically do). But it still wouldn’t solve how to set the data context of a user control to view-model built by Ninject, using declarative XAML code. This troubled me for a few days, and after thinking it through, trying some different approaches, and talking discussing it with Nate Kohari the solution turned out to be Service Locators. This is a different pattern used to implement Inversion of Control, and often you decide to use either service locators or dependency injection. I recommend reading the section on service locators vs. dependency injection in Fowlers essay for a good description of the pattern.

The short version of the pattern is that a service locator is a registry holding references to all the services used by your application. A class, such as the view-models in YouCard, can ask the service locator to give them an implementation of IPhotoService or ITwitterService. The big difference between service locators and dependency injection is that with SL your classes asks for an implementation, but with DI they are given an implementation (pull vs. push). Nate has blogged about how Ninject plays nicely with service locators.

"I don’t think that service locators and dependency injection are mutually exclusive; in fact, I’ve found that it can actually be very effective when used in conjunction with a dependency injection framework like Ninject. – Nate Kohari"

The service locator I’ve created for YouCard is fairly straight forward.

Code sample 10

In many cases you implement the service locator as a static class. That was not an option, as Silverlight 2 doesn’t support data binding to static classes. The way I solved this was to make a static constructor, and a private, static kernel field. The static constructor is the first thing executed in the class, before any standard constructors. The static constructor checks if we have a kernel and if not it instantiates one using module containing our binding configuration. By making the kernel field static we can ensure that we have only one instance of it in our application. The class has two instance properties that surface our view-models from the kernel, as well as a generic instance method to get any object from the container.

Before introducing dependency injection we bound our views to the view-model declaratively like this:

Code sample 11

After introducing a service locator we need to change this around a little. The first thing we do is to instantiate the service locator as an application level resource:

Code sample 12

Then for each of the views we need to change how they get their data context.

Code sample 13

Each of the views gets their view-model by data binding to properties on the service locator. The coolest thing about this approach is that we still get full Blend design time support with sample data provided through the mock services.

Conclusion

Introducing dependency injection in Silverlight isn’t any harder than in other .NET applications. The strong focus on keeping the framework light weight and extremely fast makes Ninject a perfect fit for Silverlight. However, one could argue that for a simple example like this Ninject isn’t really necessary. I could hand-write the dependency injection code inside my service locator, and eliminate the Ninject dependency, and still get the flexibility of dependency injection. On the other hand, Ninject is only 110KB (before it’s zipped into the XAP file), and isn’t going to add a lot of download weight to your application. 100KB is less than half the size of the images used as illustrations in this blog post...

Seperation of Concerns - The way of a true master

By using dependency injection you keep your code more flexible and testable, something that is just as important for Silverlight applications, perhaps even more, are UI requirements are likely to change a lot as you discover the power of Silverlight. I strongly believe in providing designers with a best possible experience inside Blend, and there is no reason for dependency injection to change that.

MacGyver saves the day! After the iPhone 3G release two weeks ago the web has been flooded with articles praising this eighth wonder of the world. I’ve been using the first gen iPhone since December, and have been really happy with it. I guess my biggest issue with the phone has been the crappy camera (which sadly isn’t improved in the second gen iPhone). Since I’m running a jailbreaked phone I haven’t been able to update to 2.0, until now.

On Sunday the code wizards in the “iPhone dev-team” released the much awaited Pwnage 2.0 tool. Currently it’s only available on the Mac, but there are tutorial describing how to use a prebuilt IPSW file and jailbreak your iPhone 2.0 from a PC. I used my girlfriends Mac to upgrade to 2.0, unlock and jailbreak my phone. The only issue I had was a popup in the Pwnage tool asking if “I’m a legit iPhone user”… Well, I didn’t steal the phone, so I guess yes..? Well, turns out this question determines if your phone gets unlocked and jailbreaked, or just jailbreaked. Had to run the tool twice, and answer NO to this question to get it to work.

One of the things I’ve been missing the most after changing job and mobile last year is the Exchange support in Windows Mobile. Thankfully this is one of the big things on the iPhone 2.0. One of the things I did some time back was to consolidate all my e-mail accounts through Google Apps for your domain, and Google have been hosting the mail for follesoe.no for over a year now. With added IMAP support Gmail works great from any client application, as well as on the iPhone. I haven’t had a good way to manage contacts and calendars, but I want to use Google Apps as the master, and then sync it with both my iPhone and my PC. Unfortunately Google does not support the Exchange ActiveSync protocol natively, but there are third party services that will gateway your Google Calendar and Contacts and provide Exchange access to it. One of those services is the easy to use, free service from NuevaSync. I came across this service in a blog post titled “Using Google as a *free* Mobile Me Alternative with NuevaSync”.

After configuring NuevaSync I needed to find a way to get my contacts from Outlook 2007 and into Gmail Contact. The optimal solution would be to connect directly from Outlook 2007 to NuevaSync. I was a little bit surprised to learn that you can’t force Outlook 2007 to use the Exchange ActiveSync protocol used by mobile devices. Since NuevaSync doesn’t support the full RPC protocol used by Exchange this wasn’t an option. So my second alternative is to find a way to sync my local computer with Google Calendar and Google Contacts.

People have had mixed experiences with Google Contacts. Gmail can clutter your address book by automatically adding people you communicate with. This is now an optional feature, and you can disable automatic adding of contacts. After disabling this feature and deleting all existing online contacts I was ready to do the syncing. Problem is that I couldn’t find any good tools to do this. There is a free tool from Google that will sync your calendar, but it doesn’t support contacts. OggSync is another alternative. But the free/trail version doesn’t support contacts either, and I’m not paying until I’m sure it works nicely.

The solution to my problem turned out to be open source software. I’ve been a big fan of Firefox for a long time, and figured this might be a good time to check out Thunderbird. Setting up Thunderbird with Google IMAP is a breeze, and well documented by Google. Thunderbird also supports contact imports from Outlook 2007, so I didn’t have any problems getting my contacts into Thunderbird. To synchronize contacts between Google Contacts and Thunderbird I used the Zindus add-on. Thunderbird doesn’t come with a calendar out of the box, but with the official Mozilla Lightning extension you get both calendar and tasks support in Thunderbird. I also had to install a “Provider for Google Calendar” add-on to get Lightning to sync with Google Calendar. My current setup now looks something like this:

My iPhone sync setup

I have to agree that it might look a little bit messy, but it works. And it’s free! It’s just something really pleasing of being able to add a appointment on the iPhone, and seconds later see it show up both in my online Google Calendar, and in Thunderbird. Or to edit a contact in Thunderbird, and moments later have it updated both in Gmail and on my phone. I’m quite happy with the current setup. And the important part is that the “master store” is kept on my Google Apps for your domain account.

And for the other new stuff in 2.0: the app store is just AMAZING! So many great apps, really nicely integrated both on the phone and in iTunes. So far my absolute favorite app is the iTunes remote control application. I’ve used Pocket PC based remote control software, but this one is just awesome! Now the only thing missing is an equally good Vista Media Center remote control, and the iPhone just became the coolest media remote ever.

If you haven't upgraded yet, go do it!

This is a post I've been looking forward to write for quite some time, but I've just been to busy with work, CodeCampOz and REMIX to get around to do it… At the MVP Summit in Seattle some weeks back I had dinner with a group of friends, including fellow RD and co-worker Sondre Bjellås, and long time IRC-friend Wilco Bauwer (now working at Microsoft). Like when ever a group of programmers get together the talk soon was about Silverlight, C# and programming an general. We started discussing Silverlight and what features we would love to se in future versions. One of the things Sondre felt was missing is support for microphone and webcam. I don't know why Sondre think this is a big deal (but he DO read Love and Sex with robots… btw, Sondre, you should write a book review!). Wilco have worked on the HTML-bridge in Silverlight, so we started talking if it might be possible to "cheat" basic webcam support by bridging Silverlight and Flash. Without knowing the details we all agreed that it was probably possible to do.

When I got back from Seattle I started doing some initial research, like learning how to program against the webcam in Flash, what kind of HTML-bridging  capabilities you got and so on. A video tutorial titled "Webcams, PNG and AIR", combined with a blog post titled "Use JavaScript to Take a Screenshot of a Flash movie", gave me all the pieces to build webcam support for Silverlight (using Flash). So I asked my self: "What would MacGyver do", and decided to glue everything together into a proof-of-concept of webcam support in Silverlight 2.

The video tutorial covers the basics of how to create a camera object, attach it to a video and grab a video frame as a BitmapData object. It also covers how to use the as3core library, a set of open source extensions to ActionScript3, which includes a PNG-encoder class. The PNGEncoder encodes a BitmapData object into a ByteArray. Once I had the ByteArray I needed a way to pass it back to the browser. Since the set of types you can marshal between ActionScript and the browser (at least to my knowledge) is limited, I figured a Base64 encoded string would be the way to go. The blog post about taking screenshots used this technique to pass an image from Flash to JavaScript. It also covered how to expose ActionScript functions to JavaScript using the ExternalInterface APIs.

Once I had the Base64 encoded PNG image in JavaScript I could simply return it back to Silverlight, which then would use the Convert.FromBase64String method to create a byte array. With the image stored in a byte array I could simply load it into a MemoryStream, and then set the MemoryStream as the source of a BitmapImage object.  I'll let MacGyver show you how it all comes together:

MacGyverUML

It literally didn't take more than 20 lines of ActionScript, 5 lines of JavaScript and 5 lines of C# to get a single frame from my webcam onto a Silverlight image control.  This first piece of code is the ActionScript needed to start the webcam, capture a frame, set the mode and expose two functions to the browser:

WebcamActionscript

The next part is the JavaScript needed to grab the object/elem tag containing the Flash player, and calling the ActionScript functions to grab a snapshot from the webcam. The Base64 string is just returned from the function, as this function is being called from C#:

WebcamJavascript

The final part is the C# code using the HTML bridge to invoke the JavaScript function, grab the Base64 string, decode it, and then load the PNG image:

WebcamCSharp

Using the basic webcam integration I created two sample applications. The first one is a "performance test" to see how many frames per second I'm able to transmit to Silverlight. Since I'm not able to pas the raw stream from the camera, and have to PNG encode each frame, it's all CPU bound. The application uses a timer, which will grab a frame and measure the time it takes. Once it got the frame it will adjust the interval of the timer to the amount of time spent on the previous frame + 50 milliseconds (to give the UI thread some room to handle input events etc). I was able to get roughly 12fps 180x140, but on higher resolutions it starts to get sluggish. Also note that when using all the CPU power to capture frames you don't have CPU left to do Silverlight animations etc, so doing "live" video is really something you don't want to do. Click the image to check out the sample:

WebcamLiveVideo

The second sample is a Silverlight "Photo Booth" application, with out any of the cool features of the real Apple Photo Booth app. The interesting part about this sample is how I overlay the Flash container on top of Silverlight. This way my Silverlight application don't need to use CPU power to pre-view the video, and I only grab photos when the user clicks the button. Each image is also added to the thumbnail control, which I re-used from my YouCard demo. Click the image to check out the sample:

WebcamPhotobooth

I've made the code available for everyone to play with, including the Flash webcam wrapper. In order to build the Flash app you need Adobe Flash CS3. If you don't have Adobe Flash CS3 you can still build the app in Visual Studio and use the prebuilt WebcamWrapper.swf file. The code is not optimized in any way, and probably contains some bugs. But, this initial post is meant as a proof-of-concept, and I'll probably revisit this topic later.

And to summarize: THIS is how MacGyver would have built webcam support for Silverlight 2!

One of the cool features of Silverlight 2 is the support for cross-domain web requests. This enables you to call web APIs directly from your Silverlight client without proxying the request through your own server. The service you’re calling must provide a policy file permitting cross-domain callers. This is the same security mechanism used by Flash to make cross-domain calls, and in fact Silverlight 2 respects the same crossdomain.xml format as Flash. Any service callable by Flash is now callable by Silverlight 2. If you want to learn more about Silverlight networking and cross-domain calls check out Karen Corby excellent three part series on the Silverlight HTTP Network stack.

Several popular Web 2.0 services, like Flickr, have a crossdomain.xml file that allows for cross-domain Silverlight clients. Others, like Twitter, have a more restricted crossdomain.xml file that only allows callers from certain domains. Most sites however don’t provide a crossdomain.xml, so for instance if you want to consume their RSS feed you need to proxy the request through your server. 

Today I started on a new Silverligh project where we want to consume RSS feed, and I was just about to add my “standard” WCF proxy to the project when my old friend Yahoo Pipes came to mind. I’ve previously blogged about how I use Yahoo Pipes to merge my blog posts with my mobile photos on Flickr and then import it to Facebook. Yahoo Pipes is a really cool service that let’s you define fairly complex web integrations using drag-and-drop. You drag different sources, filters and operations on a design service and “connect” the pipes together to pipe and transform the data. When I checked http://pipes.yahoo.com/crossdomain.xml I was a little disappointed to get a 404, but after digging around a little it turns out Yahoo host their APIs on a different URL: http://pipes.yahooapis.com/crossdomain.xml. Yahoo Pipes supports cross-domain callers!

 yahoopipefeedproxy

I quickly created a really simple pipe. It uses the URL input module to retrieve the URL of the feed, the Feed-Fetch module to read the feed and then output it. Click for an example of my feed proxyed through Yahoo Pipes. The following code shows how to consume the feed in Silverlight 2:

private void DownloadFeed()
{
    string pipeUrl = "http://pipes.yahooapis.com/pipes/pipe.run?_id=4rBri9Ef3RG8CEGLLe2fWQ&_render=rss&feedUrl=";
    string feedUrl = "http://feeds.feedburner.com/follesoe";
    string url = string.Concat(pipeUrl, HttpUtility.UrlEncode(feedUrl));

    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
    request.BeginGetResponse(new AsyncCallback(ResponseHandler), request);
}

private void ResponseHandler(IAsyncResult asyncResult)
{
    HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
    HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);

    if (response.StatusCode == HttpStatusCode.OK)
    {
        XmlReader reader = XmlReader.Create(response.GetResponseStream());
        SyndicationFeed newFeed = SyndicationFeed.Load(reader);
    }
}

I tried to make a more general purpose proxy-pipe using the “fetch data” module which can fetch XML, RSS, KML and iCal data. Unfortunately Yahoo Pipes can only output RSS, JSON or serialized PHP, but not plain XML. I tried piping my public Twitter feed (XML) through it, and it works fine. The only problem is that it makes some changes to the output, like adding the name of the pipe, the number of elements etc. So it’s not a “raw” data proxy, something you have to take in account when consuming the output of the pipe. Click for my Twitter feed outputted as a JSON array of tweets.

Below is a simple RSS reader (hosted on Silverlight streaming) I wiped up in 45 minutes that consumes any RSS feed through Yahoo Pipes! The code is off course available for download. For more Silverlight godness - come to REMIX!

One of the new features introduced in .NET 2.0 is the Event-based Asynchronous Pattern.  A class that supports this will have one or more methods named MethodNameAsync. These methods often mirror synchronous versions, which perform the same operation on the current thread. The class may also have a MethodNameCompleted event and it may have a MethodNameAsyncCancel method.

The Event-Based Asynchronous Pattern is used several places in the .NET 2.0 Framework , and one example many might find familiar are the auto generated Web Service Proxy classes. For every web service method you get a async version, and an event fired when the async method call finishes. The data is returned as the event argument.  Code like this is really nice to work with, and makes it really simple to make more responsive clients where all web service calls happens on a separate thread. The disadvantage with asynchronous code is that it's harder to write unit tests for.

This is a problem I've faced many times, and I've seen several different solutions. Many of them involves sleeping the thread executing the test, while waiting for the data to come back so that you can do any assertions on the returned data. This has several disadvantages. You don't now exactly how long the asynchronous call is going to take, so you need to sleep "long enough". Having thread sleeps in your tests are going to (big surprise) make your test suite slow. Now matter how fast your service returns it data, you still have to wait for all thread sleeps before the test ends. This is really inefficient, and can really become a problem when you have a large test suite integrated into a build environment. Another problem is that this is an unreliable way to do your testing, as they might pass some times, while fail others (if the thread sleep isn't long enough).

The best solution I've found to unit testing of asynchronous code is the ManualResetEvent class found in the System.Threading namespace. I'm no threading expert, and I'm not going to try to explain how the .NET threading model works, but I've included a little snippet from the MSDN documentation explaining what you can use the ManualResetEvent class for:

"ManualResetEvent allows threads to communicate with each other by signaling. Typically, this communication concerns a task which one thread must complete before other threads can proceed".

This is exactly what we want. When the thread executing the unit test starts an asynchronous call we want to block the thread, and wait for a signal from the callback before we continue. This way we spend the minimal time needed waiting for a result from the async method call, and don't have to depend on thread sleeping for synchronizing the test with the result from the async method. I've included a simple NUnit test for a web service offering basic arithmetic operations. It calls the async versions of the add and subtract methods, performs assertions both on the returned data, and check if the async call actually completed. The details on how to use the ManualResetEvent is included in the code sample beneath (check the comments).

[Test]
public void TestCalculations()
{
    // A simple web service offering basic aritmetich operations
    Service service = new Service();

    // Test data...
    int a = 10;
    int b = 10;

    // Variables to track is a asyn call completed.
    bool addCompleted = false;
    bool substractCompleted = false;

    // Used to signal the waiting test thread that a async operation have completed.
    ManualResetEvent manualEvent = new ManualResetEvent(false);

    // Async callback events are anonomous and are in the same scope as the test code,
    // and therefore have access to the manualEvent variable.
    service.AddCompleted += delegate(object sender, AddCompletedEventArgs args)
    {
        // Some basic assertions on the code.
        Assert.AreEqual(a + b, args.Result);
        addCompleted = true;

        // Signal the waiting NUnit thread that we're ready to move on.
        manualEvent.Set();
    };
    
    service.SubstractCompleted += delegate(object sender, SubstractCompletedEventArgs args)
    {
        Assert.AreEqual(a - b, args.Result);
        substractCompleted = true;
        manualEvent.Set();
    };

    // Call the add method asyncronous.
    service.AddAsync(a, b);

    // Block the current thread untill the callback event signals
    // or the call times out (1500 ms).
    manualEvent.WaitOne(1500, false);

    // Check if we completed the async call, or fail the test if we timed out.
    Assert.IsTrue(addCompleted);

    // Set the event to non-signaled before making next async call.
    manualEvent.Reset();

    service.SubstractAsync(a, b);
    manualEvent.WaitOne(1500, false);
    Assert.IsTrue(substractCompleted);
}

Earlier this month I started on a new project at Schlumberger in Trondheim. One of the first things I do on a new project is getting the development environment up and running. Setting up a source repository, automated builds, testing and deployment and so fourth. We're not using Team System on this project, so for testing we use NUnit. On previous projects I've used the TestDriven.NET VS2005 plug-in with great success. It's basically a plug-in that lets you right click a test project, test class or test case and select run test or debug test. This makes it much easier to run your test than having to depend on the NUnit test console. And if you want to debug your tests you don't have to attach the debugger to the NUnit test console, you can do everything directly from VS2005.

 

Some time late 2006 TestDriven.NET started charging money for their plug-in. Not a significant amount, but enough to take away some of the sweet taste of the product. Another problem is buying tools like this in large organizations, where there might be political reasons/management directives stating that we use this toolset in our development suite. It's way easier to get away with a free/open source tool than something you have to file an expense report to buy and download.

 

Thankfully there is an excellent (perhaps even better) alternative to TestDriven.NET for your unit testing needs. JetBrains, the company behind ReSharper and IntelliJ (among many Java developers considered the best IDE available)  have written an excellent VS2005 plug-in called UnitRun which does exactly what TestDriven.NET did. And best of all: it's free! UnitRun is developed by the ReSharper team, and they sure know how to write high quality Visual Studio plug-ins. It looks really good, and the integration is really tight, both in code view, the solution explorer and everywhere else in VS2005.

 

unitrunpopupMenu.gif

 

I've included some screens to give you an idea of what UnitRun has to offer. If you're doing unit testing (off course you do), and don't use VS Team Suite I would strongly recommend downloading UnitRun to make testing a bit more pleasant.

 

unitTestRunnerWindow.gif

When ever you click on a hyper link like http://jonas.follesoe.no, mailto:me@email.com the Windows component "Url.dll" will do a look up in the register and execute the correct application. For links to regular web pages it will launch your default browser. For mailto links it'll launch your preferred e-mail client. You can use the link concept in a wide range of applications, ranging from linking inside web pages to adding links to e-mail messages, spread sheets, word documents, sidebar gadgets, IM chats and more. The way we can link information together is one of the core fundamentals of the web. Applications that handle a specific type of links is called a protocol handler. In this post I'll discuss how you can create your own protocol handler for a custom application and how this might be a powerful way to achieve light weight  and easy to implement integrations between your applications.

helpdeskclient

To illustrate the concept of protocol handlers I've created a simple Windows Forms Application called HelpDeskClient. The application can be looked at as your typical line of business application you want to "tap into" from other applications. The application contains code to write/delete the registry keys needed to register the protocol handler. To illustrate some simple "integration" the application hosts a HttpListener (a small web server) to display some simple HTML and RSS. The application is implemented as a single instance application, meaning that there will only be one instance of HelpDeskClient.exe running at any time.

To register a new protocol handler all you need to do is add a few lines to the registry:

[HKEY_CLASSES_ROOT]
  [helpdesk]
    (Default) = "URL:HelpDesk Protocol"
    URL Protocol = ""
    [DefaultIcon]
      (Default) = "HelpDeskClient.exe"
    [shell]
      [open]
        [command]
          (Default) = "c:\whatever\HelpDeskClient.exe "%1""

The most important part is the URL Protocol value under the "helpdeks" key. This will register the helpdesk:// protocol with "Url.dll". When ever Windows encounters a helpdesk:// link "Url.dll" will execute your HelpDeskClient.exe file passing the URL as a command argument. So when "Url.dll" executes a link to "helpdesk://open/?id=7" it'll execute "c:\whatever\HelpDeskClient.exe helpdesk://open/?id=7". In your main method you need to parse the arguments and take appropriate action. Fore another example on how to create a Visual Source Safe protocol handler check out this CodeProject article.

To make things easy the application can write/delete the registry keys needed to register the protocol handler. The code to do that looks as follow:

RegistryKey helpDesk = Registry.ClassesRoot.CreateSubKey("HelpDesk");
helpDesk.SetValue("", "URL:HelpDesk Protocol");
helpDesk.SetValue("URL Protocol", "");

RegistryKey defaultIcon = helpDesk.CreateSubKey("DefaultIcon");
defaultIcon.SetValue("", Path.GetFileName(Application.ExecutablePath));

RegistryKey shell = helpDesk.CreateSubKey("shell");
RegistryKey open = shell.CreateSubKey("open");
RegistryKey command = open.CreateSubKey("command");
command.SetValue("", Application.ExecutablePath + " %1");

When you have your protocol handler registered you need to parse the command line arguments. In this example I've created a single instance application, meaning that any attempt to start "HelpDeskClient.exe" while the application is running will not create a new instance. Instead it'll show the all ready running application. Single instance applications are quite common, Outlook 2007 is one example of it. There are several ways to implement single instance applications. If the name of the executable is unique you can simply check the list of running processes. A better way is to use a mutex. If the mutex is used it means the application is all ready running. The easiest way however, if you're writing.NET 2.0 code, is to derive the WindowsFormsApplicationBase class which is part of the "special" VB.NET libraries. The VB guys has always had a few extra classes to help them out, like the "My.*" namespaces introduced in .NET 2.0. The cool thing about .NET is that you can take advantage of these classes your self. All you have to do is to add a reference to "Microsoft.VisualBasic.dll" in your C# application. I guess this will raise a few eyebrows in the C# camp, but trust me, it's safe! Below is my SingleInstanceApplication.cs and Program.cs class. If you want to learn more about how to create single instance applications check out this blog post.

    /// <summary>
    /// The Main class of the application.
    /// </summary>
    static class Program
    {
        // Private members
        private static MainForm mainForm;

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            //Creates a new SingleInstanceApplication (from the VB Namespace)
            SingleInstanceApplication app = new SingleInstanceApplication();
            app.StartupNextInstance += new StartupNextInstanceEventHandler(app_StartupNextInstance);

            //Creates the MainForm and loads the application.
            mainForm = new MainForm();
            app.Run(mainForm);
        }

        /// <summary>
        /// Method executed if the application is allready running.
        /// </summary>
        static void app_StartupNextInstance(object sender, StartupNextInstanceEventArgs e)
        {
            //Tels the loaded main form to parse the command line arguments.
            List<string> list = new List<string>(e.CommandLine);
            mainForm.ParseCommandLine(list.ToArray());
        }
    }

    /// <summary>
    /// A SingleInstanceApplication extending the application base. Part of the VB namespaces.
    /// </summary>
    public class SingleInstanceApplication : WindowsFormsApplicationBase
    {
        public SingleInstanceApplication(AuthenticationMode mode) : base(mode)
        {
            InitializeAppProperties();
        }

        public SingleInstanceApplication()
        {
            InitializeAppProperties();
        }

        protected virtual void InitializeAppProperties()
        {
            this.IsSingleInstance = true;
            this.EnableVisualStyles = true;
        }

        public virtual void Run(MainForm mainForm)
        {
            List<string> list = new List<string>(this.CommandLineArgs);
            mainForm.ParseCommandLine(list.ToArray());
            this.MainForm = mainForm;
            this.Run(list.ToArray());            
        }
    }

As the title of this post suggests the idea of using protocol handlers is that they can be used as a ultra thin layer of integration between your applications. I'll try to elaborate more on this…. Most Windows applications supports some kind of hyper linking. You can type in a link in a mail message, a Word document, an Excel spread sheet and off course on any HTML page. This opens up for some simple "work flows" that just works. I can write an e-mail, paste a link and tell some one to check out this cool YouTube video… Or I can look up and address on Google Earth and copy the location as an hyper link and send it to some one on MSN Messenger. By registering your own protocol handler you can open up to this kind of "integration" your self. By creating some kind of URL scheme to navigate to important parts of your Windows application, open up customers or help desk requests (as in this example) you can open up for some really fluid and easy to implement workflows for your end users. For instance you could send an e-mail to your manager telling them to "help you out with this item", and hyper link directly into your ERP system. Or even more interesting you could start exposing feeds of important items that your users could integrate in any way they want. You could subscribe to "my work items" in any RSS application, and clicking the link would bring up the correct application, pre-loaded with that specific item. You could write a few neat Sidebar Gadgets providing glanceable data from your business applications  saving your users from having to click through several screens just to check if they have any urgent items to take action on.

helpdeskword

To illustrate this (and provide some XML data for further examples) the HelpDeskClient application will start a HttpListener when it loads. You register the HttpListener on any url and port (under local host off course) and can start serving incoming HTTP requests. When a request is received you get access to the HttpRequest object you're used to from ASP.NET and can start creating the HttpResponse. In this example I serve two URLs: http://localhost:8080/taskhtml/ and http://localhost:8080/taskfeed/. The first one servers a simple HTML page with a list of open and closed items. Each item is a helpdesk://open/?id=xx link. When you click the link the HelpDeskClient application will execute and show the selected item. The feed page is a RSS 2.0 feed with all open help desk requests. This feed can be added to any RSS reader, or integrated into a Vista Sidebar Gadget or used where ever you want.

helpdeskweb  

The code to create a HttpListener is shown below:

        /// <summary>
        /// Starts the Http Listener on a background thread.
        /// </summary>
        private void StartHttpListener()
        {
            if (HttpListener.IsSupported)
            {
                try
                {
                    //Creates a HttpListener with two urls for RSS and HTML.
                    HttpListener listener = new HttpListener();
                    listener.Prefixes.Add("http://localhost:8080/taskfeed/");
                    listener.Prefixes.Add("http://localhost:8080/taskhtml/");
                    listener.Start();
                    while (true)
                    {
                        HttpListenerContext context = listener.GetContext();
                        HttpListenerRequest request = context.Request;
                        HttpListenerResponse response = context.Response;

                        //Checks if the user is requesting the HTML page or the RSS feed.
                        if (context.Request.RawUrl.EndsWith("feed"))
                        {
                            //Renders the RSS feed.
                            context.Response.ContentType = "application/xml";

                            XmlTextWriter xmlWriter = new XmlTextWriter(context.Response.OutputStream, Encoding.UTF8);
                            xmlWriter.WriteStartDocument();
                            xmlWriter.WriteStartElement("rss");
                            xmlWriter.WriteAttributeString("version", "2.0");
                            xmlWriter.WriteStartElement("channel");
                            xmlWriter.WriteElementString("title", "HelpDesk Application - Open Requests");
                            xmlWriter.WriteElementString("description", "An RSS feed of open HelpDesk Requests. Can be used by gadgets, feed readers etc.");
                            xmlWriter.WriteElementString("link", "http://localhost:8080/taskhtml/");
                            foreach (HelpDeskRequest hr in logic.RequestDatabase)
                            {
                                if (!hr.Closed)
                                {
                                    xmlWriter.WriteStartElement("item");
                                    xmlWriter.WriteElementString("guid", hr.ID.ToString());
                                    xmlWriter.WriteElementString("title", hr.Subject);
                                    xmlWriter.WriteElementString("link", "helpdesk://open?id=" + hr.ID.ToString());
                                    xmlWriter.WriteElementString("pubDate", hr.Date.ToString("r"));
                                    xmlWriter.WriteEndElement();
                                }
                            }
                            xmlWriter.WriteEndElement();
                            xmlWriter.WriteEndElement();
                            xmlWriter.WriteEndDocument();
                            xmlWriter.Flush();
                            xmlWriter.Close();
                        }
                        else
                        {
                            //Renders the HTML page.
                            context.Response.ContentType = "text/html";
                            StringBuilder sb = new StringBuilder();
                            sb.Append("<html><head><title>HelpDesk Application</title>");
                            sb.Append("<link rel='alternate' type='application/rss+xml' title='HelpDesk Request Feed' href='taskfeed' />");
                            sb.Append("<style>body { font-family: verdana; }</style></head><body>");

                            sb.Append("<h1 style='color: red;'>Open HelpDesk Requests</h1><ul>");
                            foreach (HelpDeskRequest openItem in logic.RequestDatabase.FindAll(delegate(HelpDeskRequest hr) { return !hr.Closed; }))
                            {
                                sb.Append(string.Format("<li><a href='helpdesk://open?id={0}'>{1}</a></li>", openItem.ID, openItem.Subject));
                            }

                            sb.Append("</ul><h1 style='color: green;'>Closed HelpDesk Requests</h1><ul>");
                            foreach (HelpDeskRequest closedItem in logic.RequestDatabase.FindAll(delegate(HelpDeskRequest hr) { return hr.Closed; }))
                            {
                                sb.Append(string.Format("<li><a href='helpdesk://open?id={0}'>{1}</a></li>", closedItem.ID, closedItem.Subject));
                            }
                            sb.Append("</ul></body></html>");

                            StreamWriter streamWriter = new StreamWriter(response.OutputStream);
                            streamWriter.WriteLine(sb.ToString());
                            streamWriter.Flush();
                            streamWriter.Dispose();
                        }
                        response.Close();
                    }
                }
                catch (Exception)
                {
                    MessageBox.Show("Unable to start HttpHandler. Are you running this application as an administrator?", "Running as administrator?", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

This post fits nicely together with yesterdays post on how gadgets can bring the service oriented architecture all the way to the desktop. By creating a protocol handler for your line of business application you provide a ultra thin layer of integration to hook into from "any" application. This simple concept could make your users more productive, save them lots of clicking, and open up to some nice workflow integrations. I hope you found the posting interesting, and as usual all comments are more than welcome! Before I wrap up, a few of disclaimers. The application has to run as administrator under Vista (because of registry settings and HttpListeners).Using protocol handlers like this isn't expressed best practices from Microsoft and can only be considered an idea I'm throwing out in the open. I haven't implemented it in any real world applications my self yet.

Jeff Atwood over at Coding Horror wrote a blog post about JavaScript being "The Lingua Franca of the Web". More and more developers are building fairly large object models and frameworks in JavaScript. Microsoft's own Ajax library is one example of this. The Dojo Toolkit is another. It looks like no matter where you turn, weather it's to Ajax web sites, Silverlight applications or Sidebar gadgets you're stuck with JavaScript as your programming language. It was about time Microsoft did something about the poor tool support for writing JavaScript in Visual Studio Orcas 2008.

The way Microsoft have solved the IntelliSense problem is really elegant. In order to do good IntelliSense you need a formal way to comment your code. You have to tell the IDE which parameters your functions expects and what they'll return back. The way you annotate your JavaScript to get IntelliSense in Visual Studio 2008 is by using Microsoft's all ready familiar XML commenting syntax (with a few twists). The next problem is that JavaScript is a scripting language (hence its name), so the IDE can't compile the code to do reflection. It has to interpret it dynamically. The problem is to figure out which other scripts will be loaded into scope by the time the script you're working is executed. When developing web apps you might have some inline JavaScript and other pieces in external JavaScript files. The way you hint to the IDE which scripts are loaded into scope is with a special "reference" comment. You tell Visual Studio which scripts you have "referenced" in your application. A simple example of this is included below. If you want a thorough introduction to the new JavaScript Doc commenting syntax in Visual Studio check out the post by Bertrand Le Roy from the ASP.NET team or this post by Scott Guthrie.

System.Gadget = function()
{
    /// <summary>Defines methods, events, and properties that are used to specify gadget configuration options in the Windows Sidebar environment.</summary>
    /// <field name="background" type="String">Used in a gadget to set the background image using a file path or to get the file name of the current background image.</field>
    /// <field name="docked" type="Boolean">Called from within a gadget to determine if the gadget making the script call is docked.</field>
    /// <field name="name" type="String">Used from within a gadget as a means to determine the gadget name as specified in the gadget manifest file.</field>
    /// <field name="opacity" type="Number" integer="true">Called from within a gadget to specify the percentage of opacity as an integer.</field>
    /// <field name="path" type="String">Called from within a gadget to display the file path for the gadget.</field>
    /// <field name="platformVersion" type="String">Called from within a gadget to retrieve the version of the gadget platform that the gadget is running on.</field>
    /// <field name="settingsUI" type="String">Called from within a gadget to specify the settings to display to the user and activate the user interface so that the user can bring up the Settings dialog box.</field>
    /// <field name="version" type="String">Called from within a gadget to retrieve the version of the Microsoft Windows operating system that the gadget platform is running on.</field>
    /// <field name="visible" type="Boolean">The gadget's visibility status.</field>
    this.background = "";
    this.docked = false;
    this.name = "";
    this.opacity = 0;
    this.path = "";
    this.platformVersion = "";
    this.settingsUI = "";
    this.version = "";
    this.visible = false;    
}

The next piece of the JavaScript IntelliSense puzzle is to figure out how to represent the object model in a clean way in the IntelliSense popup window. JavaScript don't have any built in structures for interfaces, events, properties, name spaces, classes and methods; things we take for granted in the .NET framework and other object oriented programming languages. How ever JavaScript do support many object oriented programming concepts, and in the later years this have been exploited to the full extend by developers to build fairly complex object models. Ray Djajadinata wrote an excellent article for the May 2007 issue of MSDN Magazine on how to "Create Advanced Web Applications With Object-Oriented Techniques". In his article he discuss how to use object-oriented techniques to build more manageable and better scripts for your web applications.

After reading the article I figured I'd give the new JavaScript functionality in Visual Studio 2008 a go and build my own object model in JavaScript. VS did a good job ad aiding me in my JavaScript development, but my JavaScript object model didn't turn out as nice as the Microsoft Ajax Library. I couldn't figure out how to arrange classes into name spaces, how to implement an interface and so fourth. But since Microsoft have open sourced the client side of their ASP.NET Ajax framework all I had to do was to take a quick peek at the source code to figure out how they where doing their magic. Turns out the Ajax team have built something they call the "Type class", which is a typing and reflection system for JavaScript extending the object-oriented programming functionality. Using the Type class you can add typing information about your JavaScript, and do things such as registering classes, namespaces, implement interfaces and use inheritance. Visual Studio 2008 understands this typing system, so that when it executes/interprets your script to provide you with IntelliSense it has the information needed to provide you with a familiar developer experience, with the same icons for namespaces, classes, methods, interfaces and so fourth.

After playing with the new JavaScript features in VS 2008 and seeing how easy it was to hand code JavaScript against the Ajax client libraries another large JavaScript API came to mind. The Vista Sidebar Object Model. I've previously blogged about development of Vista Sidebar Gadgets, and how to do some advanced stuff like .NET interoperability, so I'll skip the fundamentals. As part of the Sidebar Microsoft ships a Sidebar Object Model you can program against. This object model contains 25+ classes with a bunch of properties, methods and collections. Using the Sidebar Object Model you can do things like open file, get battery information, monitor network availability and so fourth. At the moment there is no tool support facilitating you when using the object model. You're pretty much stuck with the MSDN documentation. You'll find the structure and naming of the Sidebar Object Model quite familiar as a .NET developer, but you still have to check the reference to see which properties and methods each object supports. Microsoft haven't announced anything about better tool support for Sidebar Gadget development so I figured I might as well take matters into my own hands.

 SidebarIntellisense.gif 

Using the Microsoft Ajax client framework and the "typing system" provided by it I've stubbed out all the namespaces, classes, methods, collections and properties of the Sidebar Object Model. I've created a 700+ lines long JavaScript files containing nothing but an well commented (copy and paste from MSDN) object framework. So when you want IntelliSense for your Sidebar Gadget all you have to do is "add a reference" to the Sidebar.IntelliSense.js script file using the special commenting syntax described above. By including this reference comment Visual Studio 2008 will bring the Sidebar Object Model into scope when you're inside the editor. But if you don't include the Sidebar.IntelliSense.js file in a script tag in the gadget HTML file it won't affect your gadget at runtime. When you're ready to deploy your gadget you simply delete the IntelliSense script file from your gadget folder (it doesn't provide any runtime functionality anyway).

NB: The current state of the IntelliSense script is a proof of concept/prototype/sharing of an idea, and not a well tested replication of the Sidebar Object Model. If you use it and get runtime errors in your gadgets it probably means I've miss mapped some class or properties. If that's the case, just update the script your self, or drop me a comment on this post. If the gadget community picks up on this I might team up with fellow Regional Director Jeremy Boyd from New Zealand who have create a Visual Studio project template to kick-start your Sidebar Gadget development.

Last week I blogged about a performance problem I helped a colleague debug. The root of the problem was reflection based cloning of objects. Reflection based cloning can be great for maintainability and productivity, but in some cases you might get into troubles. At least if you don't know that the classes you're using are using reflection.

Anders Norås followed up on my post and blogged about other ways to implement object cloning. Yesterday he posted a great example on how to get blazing fast reflection in .NET. In his post Anders discusses how you can use the CodeDOM to generate reflection optimizers and compile them to in-memory assemblies . An even better alternative is the Lightweight Code Generation (LCG) feature of .NET 2.0. In his example cloning a customer class one million times takes about one minutte using pure reflection. The bytecode enhanced reflection takes about 175 milliseconds. Now that's some serious performance. 

"...You have a couple of options for doing optimized reflection on .NET. In general you will use the CodeDOM to generate the optimizers on .NET 1.x, while you'll use Lightweight Code Generation (LCG) on .NET 2.0. LCG bridges the gap between purely dynamic invocations and statically bound calls. The LCG feature provides the means for generating dynamic methods at runtime..." (from Anders Norås blog)

Anders has several other interesting posts on both Java and .NET development. His posts on DSL's and a LINQ implementation on Java is really interesting reading well worth checking out.

Last week I re-discovered code snippets in Visual Studio 2005. Well, at least the part about how easy it is to make your own code snippets. Don't get me wrong, I haven't typed a single property definition by hand since I installed VS2005 and the "prop" snippet (and before that I used third party plug-ins and macros to do properties). In C# 3.0 and VS2008 writing properties is even easier with the new compact property syntax. But that's a different story (which I'm going to tell in my C# 3.0 and LINQ session at MSDN Live fall 2007). This post is about code snippets.

In my last post about re-throwing exceptions I briefly described the project I've been working the last 6 months, so I'm not going to spend too much time recapping on this. The project is a v2.0 of an internal application written by the IT-department of the health region. Since this is a v2.0 much of the grunt work is all ready done, and much of the plumbing is in place. The core architecture and coding style is defined, and most of the project structure is in place. Last week we (me and Mats) where adding some new features involving some new tables in the database. Following the architecture of the application we had to add code and classes all the way through all the layers (data access, business layer, service layer, UI process layer, UI layer). The data access layer is using the Data Access Application Block from the Patterns and Patterns team, but we still did lots of copy-and-paste re-use of other pieces of "create db command, add parameters, execute stored procedure, parse result set and return entity object"-code. A typical piece of code looked something like this: 

using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnection"].ConnectionString))
{
    SqlCommand command = new SqlCommand("GetItems", connection);
    command.CommandType = CommandType.StoredProcedure;
    command.Parameters.AddWithValue("@author", "Jonas Folleso");

    using (command)
    {
        command.Connection.Open();
        using (SqlDataReader reader = command.ExecuteReader())
        {
            List<Item> items = new List<Item>();
            while (reader.Read())
            {
                Item item = new Item();
                item.ID = reader["id"] == null ? -1 : Convert.ToInt32(reader["id"]);
                item.Title = reader["title"] == null ? string.Empty : reader["title"] as string;
                items.Add(item);
            }
            reader.Close();
        }
        command.Connection.Close();
    }
}

Writhing code like this was getting boring (and inefficient) so it was time to be a true programmer and find a cleaner, easier way to solve this problem. Since most of the project structure and style was all ready set we didn't want to make to dramatic changes, and introducing fancy things like ORM's, LINQ, new base classes and whatnot was not an option at this point of the project. Instead I remembered how easy it is to create custom code snippets in VS2005. You simply create an XML file containing a snippet definition, and store the file with a .snippet extension in your "Documents\Visual Studio 2005\Code Snippets\C#"-folder.

For the code sample above we created a bunch of code snippets following the coding style all ready established in the project. We created snippets like "reader" for the core structure of executing a stored procedure and parsing the reader. We created snippets like "readint", "readstring", "readbool" and "readdate" to read columns from the result set, and we used snippets like "addint", "addstring" etc. to add columns to the command object. I've included the entire snippet definition of the "reader" snippet to give you some impression of what a custom code snippet looks like. The snippet format is well documented, and you can find a bunch of other samples online if you want to learn more about it.

<CodeSnippets
    xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>Execute Sql Data Reader</Title>
      <Author>Jonas Follesø</Author>
      <Description>A standard way to execute a stored procedure returning a reader</Description>
      <HelpUrl>http://jonas.follesoe.no</HelpUrl>
      <Shortcut>reader</Shortcut>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>spname</ID>
          <ToolTip>Name of stored procedure</ToolTip>
          <Default>mySproc</Default>
        </Literal>
        <Literal>
          <ID>connectionName</ID>
          <ToolTip>Name of the SQL connection in the configuration file</ToolTip>
          <Default>myConnection</Default>
        </Literal>
      </Declarations>
      <Code Language="csharp">
        <![CDATA[using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["$connectionName$"].ConnectionString))
            {
                SqlCommand command = new SqlCommand("$spname$", connection);
                command.CommandType = CommandType.StoredProcedure;                
                
                using (command)
                {
                    $end$
                    command.Connection.Open();
                    using (SqlDataReader reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {                         
                        }
                        reader.Close();
                    }
                    command.Connection.Close();
                }
            }]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

I've updated the snippets to make them useful for any C# programmer writing data access code by hand, using ADO.NET (the one we use at work depends on the data access application block). The snippets are packed into one ZIP file you can download and extract into your local snippet folder. If you want to squeeze some extra productivity out of Visual Studio Microsoft have uploaded a C# snippet pack (containing some of the stuff the VB guys got out of the box, but we missed out on…).
 

Exception handling is one of those things you have to learn and deal with as a .NET developer (or as a developer using many other languages and frameworks). Exception handling is a built in mechanism for detecting and handling runtime exceptions in your code. There are several things you need to keep in mind when thinking about exceptions in your application. Where do you throw your own custom exceptions? Where to you catch and log exceptions? How do you show exceptions to the end user?

The patterns and practices group have created some guidelines on how to best manage exceptions in your application, and even wrote an Exception Handling Application block. I think this block is now deprecated and have been replaced by the logging application block. Exception handling and logging tend to go hand in hand. And that's what brings me to the topic of this post; re-throwing exceptions.

I don't think I've blogged to much about my work related projects, but currently I'm working as a consultant on a project in the health care sector. The project I'm working on as a external consultant is to write a v2.0 of an internal application to manage research databases and collect electronic forms. The main goal of v2.0 is to decouple it from legacy systems in the health region so that the application can be used at other hospitals in other health regions in Norway.

Anyway, today I discovered that the way we handle exceptions in the application is a bit inconsistent so I decided to look into it. Most of the exception handling is done in the business layer where the exception is logged, before it's re-thrown (or at least that's what the developers who wrote the code thought) so that the UI can catch it and display it in a friendly manner. Most of the code looked something like this:

public static int DoSomething()
{
    try
    {
        return BusinessLayer.DoSomething();
    }
    catch (Exception ex)
    {
        Log.LogException(ex, "Something crashed...", EventLogEntryType.Error);
        throw ex;
    }
}

This is a common way to write code, and I've seen it several places. Developers thinks that this is the way to re-throw an exception. Actually it's not. When you're writing "throw ex", you're actually throwing a new exception, using "ex" as your exception object. When you throw a new exception in .NET the CLR needs to take a snapshot of the call stack and other environment variables to provide you with the information needed to debug the problem. The problem with the above example is that if some one else in a layer above you is catching the exception the stack trace will suggest that the exception occurred in ServiceLayer.DoSomething, and not in the underlying code. In some cases you actually want to hide the stack trace, and exception handling for services needs special considerations. But in most cases you actually want to re-throw the exception, to keep the stack trace correct and to save performance (taking a snapshot of the call stack and other variables are expensive).

I've created a simple example application showing the difference between throwing a new exception (as the example above) and re-throwing an exception within the catch block. The example "simulates" four layered application, with a data access layer, a business layer, a service facade and a user interface. Each layer is a simple class with one method, and the UI is the console application.

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace ExceptionTest
{
    class DataLayer
    {
        public static int DoSomething()
        {
            int a = 10;
            int b = 0;
            int c = a / b;
            return c;
        }
    }
    
    class BusinessLayer
    {
        public static int DoSomething()
        {
            return DataLayer.DoSomething();
        }
    }

    class ServiceLayer
    {
        /// <summary>
        /// Creates a new exception by throwing ex in the catch block.
        /// </summary>
        public static int DoSomething1()
        {
            try
            {
                return BusinessLayer.DoSomething();
            }
            catch (Exception ex)
            {
                Log.LogException(ex, "Something crashed...", EventLogEntryType.Error);
                throw ex;
            }
        }

        /// <summary>
        /// Re-throws the exception by calling throw; in the catch block. 
        /// </summary>
        public static int DoSomething2()
        {
            try
            {
                return BusinessLayer.DoSomething();
            }
            catch (Exception ex)
            {
                Log.LogException(ex, "Something crashed...", EventLogEntryType.Error);
                throw;
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine();
            try
            {
                ServiceLayer.DoSomething1();
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("[New exception thrown]");
                Console.WriteLine(RemoveLongPath(ex.ToString()));
                Console.WriteLine();
            }

            try
            {
                ServiceLayer.DoSomething2();
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("[Exception from data layer re-thrown]");
                Console.WriteLine(RemoveLongPath(ex.ToString()));
                Console.WriteLine();
            }
        }

        static string RemoveLongPath(string text)
        {
            return text.Replace(@"C:\Users\jonasf\Documents\Visual Studio 2005\Projects\ExceptionTest\ExceptionTest\Program.cs", @"C:\Program.cs");
        }
    }
}

The exception occurs in the data layer when dividing by 0, and is first caught in the service layer where it's logged and re-thrown.

There are two versions of the service method, one that throws a new exception by calling "throw ex;", and one re-throwing the exception using "throw;".

The output is shown in the screenshot below. Notice how the stack trace of the first call (yellow) stops in the service layer, while the second call (red) shows the entire stack trace.

Last week I got a call from a colleague who was struggling with a .NET performance issue. He's working a s a developer on a really large .NET project in the finance sector. The project is one of the largest implementations of a service oriented architecture in Norway. My colleague was working on a calculation service exposing some core calculation formulas and models used within the company. The formulas are fairly complex (I didn't understand any of it), but consisted mostly of large sums being accumulated iterative and there was no obvious reason why it took more than 3 minutes to calculate the numbers. Excel crunched the numbers in no time. Where had they had screwed up so badly?

Armed with ANTS profiler I showed up Monday afternoon to have a look at the problem. Following good programming practices the calculation service was well tested using unit tests, and they had a local test environment set up. All we had to do to profile the code was to run ANTS on one of the test suites. And the result from ANTS immediately revealed the problem. More than 99% of the entire running time of the test was spent on the EntityBase.Clone method. By following the "slowest code path" inside ANTS we managed to track down the code responsible for all the cloning. Turns out one libraries exposing "standard" math functions (relevant to the business domain) used and cloned an object derived from EntityBase. The EntityBase object is developed by another team within the business responsible for some of the core functionality across all services in the SOA architecture. The entity library was more or less a "black box" component to my colleague who hadn't thought that this might be the source of the problem.

The EntityBase class exposed some simple base functionality other developers could relay on. One of the major parts of the base class was the implementation of the IClonable interface. The IClonable is the standard way to implement deep copying of .NET objects. To make a shallow copy of an object you use the MemberwiseClone method. The implementation of IClonable in the base class used reflection to make it possible to clone any derived object with out writing any cloning code yourself. Using reflection to make your objects behavior dynamic is a really powerful concept. If you want to learn more about this there is an article and example base class for cloning objects up on The Code Project.

Using reflection is one of the most performance expensive things you can do within .NET. In some cases it's an invaluable feature, but in cases like this one it's the root of the problem. To solve the performance problem in this particular case the solution was to write a custom implementation of the Clone method on the object being cloned all the time by the math library.

By cloning the object field by field, instead of using reflection, we managed to get the time used to clone the object down from 190 to 1.5 seconds!

I've re-created the problem with a really simple example. The example is a tiny console application with one base class (BaseEntity) and one derived class (PersonEntity). The base class implements cloning using reflection, and the derived class implements a separate cloning method called QuickClone. In the Main method I create an instance of the person object and clone it 250 000 times using both Clone and QuickClone. The screenshot shows the results of the ANTS profiler. Cloning the object 250 000 times using Clone and reflection took 13.8 seconds. Cloning the object using QuickClone took 0.5 seconds… 

using System;
using System.Text;
using System.Reflection;
using System.Collections.Generic;

namespace ReflectionTest
{
    public class BaseEntity : ICloneable
    {
        public object Clone()
        {            
            object newObject = Activator.CreateInstance(this.GetType());
            FieldInfo[] newFields = newObject.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
            FieldInfo[] oldFields = this.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);

            for (int i = 0; i < oldFields.Length; ++i)
            {
                newFields[i].SetValue(newObject, oldFields[i].GetValue(this));
            }

            return newObject;
        }
    }

    public class PersonEntity : BaseEntity
    {
        private int age;

        public int Age
        {
            get { return age; }
            set { age = value; }
        }

        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public override string ToString()
        {
            return string.Format("{0}, {1} years old", name, age);
        }

        public PersonEntity QuickClone()
        {
            PersonEntity newPerson = new PersonEntity();
            newPerson.age = this.age;
            newPerson.name = this.name;
            return newPerson;
        }
    }

    public class Program
    {
        static void Main(string[] args)
        {
            PersonEntity person = new PersonEntity();
            person.Age = 20;
            person.Name = "Jonas Follesø";

            Console.WriteLine("Starting to clone...");
            for (int i = 0; i < 250000; ++i)
            {
                person.Clone();
                person.QuickClone();
            }
            Console.WriteLine("Done cloning...");
        }
    }
}

The point of this story is that if you play with reflection you might get burned. You need to know what you are doing. In this case I have no doubt that the framework guys knew what they where doing in the base entity class. I think the problem was that other teams within the company didn't know that the base class used reflection, and that this is something that might hurt performance badly. Another lesson learned is that if you have .NET performance problems, bring in ANTS right away. It's an amazing tool!

One of the cool, but perhaps overlooked features, of Outlook 2007 is the integration of mobile messaging. Today many mobile providers offers some kind of plug-in to Outlook enabling their customers to send SMS messages from Outlook. The implementation and user experience differs for each mobile provider. In Outlook 2007 there is a standard way to supports incoming and outgoing SMS and MMS messages directly from Outlook. You simply implement an XML Web Service consisting of three simple methods. There really isn't too much information available on Outlook Mobile Services in the blog sphere, so hopefully this post and webcast will be a welcome addition. In this post you'll learn how to create a Outlook 2007 Mobile Service. I've also created a screen cast that walks you through the development and deployment process.

This post is the third in a series covering free SMS messages using the Ung1881 service. The first post covered how to wrap the service into a .NET library, while the second covered how to use the .NET library from a Vista Sidebar Gadget. In this post I'm going to discuss how to implement an Outlook 2007 Mobile Service that use the same library to send free SMS messages from Outlook 2007!

Using the Ung1881 Free SMS library and Outlook 2007 Mobile Services you can send free SMS messages directly from Outlook 2007

Your Web Service only need to implement three methods, GetServiceInfo, GetUserInfo and SendXms. I've included a simple class diagram showing the methods you need to implement.

The strings passed back and fourth between server and client contains XML data. The XML structure, and Outlook 2007 Mobile Services in general, is well documented in a comprehensive developer guide up on MSDN. Last week I did some e-mailing with the team behind Outlook 2007 Mobile Services, because I couldn't get it to work by following the code samples up on MSDN. I turned out the samples where written for 1.1, and that the SOAP encoder works a little bit different in .NET 2.0. The problem was that Outlook called the service, but the parameters where always null. In the samples they use SoapRpcMethodAttribute on all methods, instead of traditional SOAP message style. But you can just overlook all the attributes and just use the WebMethod attribute as usual. The entire code of the service is fairly short (less than 200 lines) and is included below.

#region Licence agreement
// Copyright (c) 2007, Jonas Follesø
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the Jonas Follesø nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY Jonas Follesø "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL Jonas Follesø BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

using System;
using System.IO;
using System.Web;
using System.Xml;
using System.Data;
using System.Text;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Security.Authentication;
using System.Collections.Generic;
using System.Web.Services.Description;
using System.ComponentModel;

using Ung1881;

namespace Ung1881OMS
{
    /// <summary>
    /// A WebService implementing the Outlook 2007 Mobile Service interface.
    /// Allows you to send SMS messages from Outlook 2007!
    /// </summary>
    [WebService(Namespace = "http://schemas.microsoft.com/office/Outlook/2006/OMS")]
    [WebServiceBinding(ConformsTo=WsiProfiles.BasicProfile1_1)]
    public class OMSService : System.Web.Services.WebService, IOutlookMobileService
    {
        /// <summary>
        /// Returns information about the service. The returned XML contains
        /// information about the service, if it supports SMS, MMS or both etc.
        /// See the ServiceInfo.xml for more information about the XML format.
        /// </summary>
        /// <returns></returns>
        [WebMethodAttribute()]
        public string GetServiceInfo()
        {
            return ReadXml("ServiceInfo.xml");
        }

        /// <summary>
        /// Method authenticating a user and geting user information.
        /// Returns an XML string with some basic user information (phone number and e-mail).
        /// </summary>
        /// <param name="xmsUser">An XML string containing the user credentials.</param>
        /// <returns>An XML string with user information.</returns>
        [WebMethodAttribute()]
        public string GetUserInfo(string xmsUser)
        {
            try
            {
                XmlDocument xml = new XmlDocument();
                xml.LoadXml(xmsUser);

                XmlNamespaceManager nmManager = new XmlNamespaceManager(xml.NameTable);
                nmManager.AddNamespace("o", "http://schemas.microsoft.com/office/Outlook/2006/OMS");                
                
                string username = xml.SelectSingleNode("/o:xmsUser/o:userId", nmManager).InnerText;
                string password = xml.SelectSingleNode("/o:xmsUser/o:password", nmManager).InnerText;

                Ung1881Proxy proxy = new Ung1881Proxy();
                proxy.Login(username, password);
                
                return ReadXml("UserInfo.xml");
            }
            catch (Exception)
            {
                StringWriter stringWriter = new StringWriter();
                XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter);

                xmlWriter.WriteStartElement("userInfo", "http://schemas.microsoft.com/office/Outlook/2006/OMS");                
                
                xmlWriter.WriteStartElement("error");
                xmlWriter.WriteAttributeString("code", "invalidUser");
                xmlWriter.WriteAttributeString("severity", "failure");
                xmlWriter.WriteEndElement(); 
               
                xmlWriter.WriteEndElement();

                string error = stringWriter.GetStringBuilder().ToString();

                xmlWriter.Close();
                stringWriter.Dispose();

                return error;
            }
        }

        /// <summary>
        /// Method sending an SMS/MMS message to one or more recepients.
        /// </summary>
        /// <param name="xmsData">An XML string with the list of recepients and the content of the message.</param>
        /// <returns>An XML string with a status message.</returns>
        [WebMethodAttribute()]
        public string SendXms(string xmsData)
        {            
            XmlDocument xml = new XmlDocument();
            xml.LoadXml(xmsData);

            XmlNamespaceManager nmManager = new XmlNamespaceManager(xml.NameTable);
            nmManager.AddNamespace("o", "http://schemas.microsoft.com/office/Outlook/2006/OMS");

            string username = xml.SelectSingleNode("/o:xmsData/o:user/o:userId", nmManager).InnerText;
            string password = xml.SelectSingleNode("/o:xmsData/o:user/o:password", nmManager).InnerText;

            try
            {
                List<string> recipients = new List<string>();
                List<string> messages = new List<string>();

                foreach (XmlNode node in xml.SelectNodes("//o:recipient", nmManager))
                {
                    recipients.Add(node.InnerText);
                }

                foreach (XmlNode node in xml.SelectNodes("//o:content[@contentType='text/plain']", nmManager))
                {
                    messages.Add(node.InnerText);
                }

                Ung1881Client client = new Ung1881Client(username, password);

                foreach (string number in recipients)
                {
                    foreach (string message in messages)
                    {
                        client.SendMessage(number, message);
                    }
                }

                return BuildError("ok", false);;
            }
            catch (AuthenticationException)
            {
                return BuildError("invalidUser", true);
            }
            catch (Exception)
            {
                return BuildError("others", true);
            }
        }

        /// <summary>
        /// Simple helper method reading an file from disk and
        /// returning the content as a string.
        /// </summary>
        /// <param name="fileName">The relative path to the file you want to read.</param>
        /// <returns>The file content.</returns>
        private string ReadXml(string fileName)
        {
            StreamReader sr = new StreamReader(Server.MapPath(fileName), Encoding.Unicode);
            string xml = sr.ReadToEnd();
            sr.Dispose();
            return xml;
        }

        /// <summary>
        /// Simple helper method building the return XML for the SendXms method.
        /// </summary>
        /// <param name="errorCode">The error code.</param>
        /// <param name="failed">If this was a failure or not.</param>
        /// <returns>The XML fragment to return to the client.</returns>
        private string BuildError(string errorCode, bool failed)
        {
            StringWriter stringWriter = new StringWriter();
            XmlTextWriter wr = new XmlTextWriter(stringWriter);

            wr.WriteStartDocument();
            wr.WriteStartElement("xmsResponse", "http://schemas.microsoft.com/office/Outlook/2006/OMS");
            wr.WriteStartElement("error");
            wr.WriteAttributeString("code", errorCode);
            wr.WriteAttributeString("severity", failed ? "failure" : "neutral");
            wr.WriteEndElement();
            wr.WriteEndElement();
            wr.WriteEndDocument();

            wr.Close();
            string returnValue = stringWriter.GetStringBuilder().ToString();
            stringWriter.Dispose();
            return returnValue;
        }
    }
}

Once you have your service up and running you can add a new account in Outlook 2007. In the add account wizard, select "other" and "Outlook Mobile Service" as the account type. This will bring up the "Outlook Mobile Service Account" dialog. Here you enter the URL to the service and your user credentials.

 

Once you've created an Outlook Mobile Service account you get a new item in the "New" menu called "New Text Message". This brings up the new message dialog. When you send your message, Outlook will call your service and the SendXms method.

The installation process isn't as easy as I wish it was, since this is a server application you need to configure IIS. Outlook will only connect to HTTPS sites, so you need to create your own certificate as well. The screen cast walks you through this process. Scott Guthrie has a nice post on IIS7 and self signed certificates over at his blog

The next post in this Free SMS series will be an .NET 3.0 application for Windows XP users who don't have the Vista Sidebar available. Stay tuned! Please drop me a comment if you downloaded and installed the service and found it useful, or have any questions regarding Outlook 2007 Mobile Services.
 

This post is the second in a series of posts covering how to send free SMS messages using the Ung1881 web site. The first post discussed how to use screen scraping to wrap the Ung1881 web site into a .NET library we could use to send messages from the command line. In this post I'm going to discuss how to create a Vista Sidebar Gadget that allows us to use the .NET library to send free messages.

 Now that we have a nice and clean SMS library at our disposal it's time to do something more fun (and useful) than sending messages from a Console application. The next step is to create a Vista Sidebar Gadget that uses the .NET library to send SMS messages. I'm not going to walk you through the basics of a Sidebar Gadget in this post. There is an excellent article for absolute beginners up on MSDN. The focus of this post is going to be .NET interop, and how to read phone numbers from your Vista address book.

Throughout the development cycle of Vista we've seen various versions of the sidebar. I still remember seeing some awesome WPF gadgets up on Channel9 when Vista still was known as Longhorn, and all we had was early CTP builds. However, as most of you know the final version of the Sidebar is limited to HTML, CSS and JavaScript. To many (including me) this was quite a disappointment…

To be honest, it's not fair to say that Vista Gadgets can't run .NET code. You can expose your .NET code as COM object, and it's fairly easy to create COM instances from script languages.

The real problem is to register your .NET code for COM interop. This involves modifying your code to become COM compatible and to create a MSI installation package to register and distribute your code. This is to much hassle for a simple gadget.

Thankfully Tyler (he doesn't include his full name) have found a really elegant solution to .NET Interop in Gadgets, and have posted an excellent article on this on "The Code Project". You should definitely check out the article. His solution to the problems involves creating a general purpose GadgetAdapter, which is a .NET assembly, that supports COM interop, that can load other .NET assemblies dynamically using reflection. The GadgetAdapter assembly is registered on the end users machine using shell scripting from JavaScript. So the first time you use the interop layer the GadgetAdapter gets registered on the clients machine. Once the GadgetAdapter is registered you can create an instance of it from your own gadget script and load up any .NET class you want from your own assembly.

So to backup for a second, your Gadget folder structure looks something like this:

In your Gadget Script file all you have to do to create a new instance of a .NET type is this:

// Instance of the GadgetBuilder to load/unload .NET assemblies. See GadgetInterop.js.
var builder = new GadgetBuilder();         
    
// Initialize the adapter to call .NET assemblies.
builder.Initialize();

// Use the builder to add the username and password as constructor argument values.
builder.AddConstructorParam(username);
builder.AddConstructorParam(password);
    
// Load the Ung1881.dll assembly and create an instance of the Ung1881.Ung1881Client type.
ung1881Client = builder.LoadType(System.Gadget.path + "\\bin\\Ung1881.dll", "Ung1881.Ung1881Client");
    
//Get values from the UI.
var number = txtPhoneNumber.value;
var message = txtMessage.innerText;    
    
//Sending the message
var status = ung1881Client.SendMessage(number, message);

The Ung1881Client is a new class I added to the library to make it even easier to use it from a Gadget. The class takes care of wrapping long messages into smaller chunks, and it returns a status code instead of throwing exceptions when something goes wrong.

During testing of the gadget I discovered one bug/issue with the GadgetInterop JavaScript library provider by Tyler. If you turn of UAC (the "cancel or allow" stuff in Vista), or right click and run Sidebar.exe as administrator, the gadget stops working. After doing some debugging I figured out that I was unable to load the GadgetAdapter. After digging some more I located the bug in the RegisterGadgetInterop function in the GadgetInterop.js file. The problem is that if you run with out UAC, or run sidebar.exe as an administrator, you can't write to HKCU (Current User). Instead you have to register the GadgetAdapter under HKLM (Local Machine). I have notified Tyler on the Code Project message board, but article isn't updated. I've included the updated version of the RegisterGadgetInterop function below:

////////////////////////////////////////////////////////////////////////////////
//
// Add the Gadget.Interop dll to the registry so it can be used by COM and
// created in javascript as an ActiveX object
//
////////////////////////////////////////////////////////////////////////////////
function RegisterGadgetInterop()
{
    try
    {
        // Full path to the Gadget.Interop.dll assembly
        var fullPath = System.Gadget.path + assemblyStore;
        var asmPath = fullPath + assemblyName;
            
        // Register the interop assembly under the Current User registry key
        RegAsmInstall("HKCU", progID, "Gadget.Interop.GadgetAdapter", guid,
            "Gadget.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9389e9f4d8844504",
            "1.0.0.0", asmPath);
            
        if(InteropRegistered() == false)
        {
            // Try Register the interop assembly under the Local Machine registry key
            RegAsmInstall("HKLM", progID, "Gadget.Interop.GadgetAdapter", guid,
                "Gadget.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9389e9f4d8844504",
                "1.0.0.0", asmPath);
         }            
    }
    catch(e)
    {
        System.Debug.outputString("RegisterGadgetInterop fails: " + e.message);
    }    
}

Another interesting feature of the gadget is the Vista Contacts integration. Since this is an SMS gadget you obviously want to access your address book to look up mobile phone numbers of your friends and family. This is fairly straight forward, since contact support is included in the Vista Sidebar Object Model. The function reading the address book and adding contacts who have a mobile phone to a drop down list is included below:

///////////////////////////////////////////////////////////////
//
// Load contacts from the Vista address book.
//
///////////////////////////////////////////////////////////////
function loadContacts()
{
    var contactMgr = System.ContactManager;
    var contacts = contactMgr.Contacts;
    var contact = null;
    var element = null;
        
    for(var i=0; i < contacts.count; i++)
    {
        contact = contacts.item(i);        
        if(contact.mobilePhone != "")
        {            
            element = document.createElement("option");
            element.text = contact.name;
            element.value = contact.mobilePhone;
            ddlContacts.add(element, ddlContacts.options.length);
        }
    }
    
    element = document.createElement("option");
    element.value = "";
    
    if(ddlContacts.options.length > 0)
    {
        element.text = "<Velg kontakt>";
        ddlContacts.disabled = false;
    }
    else
    {
        element.text = "<Ingen kontakter>";    
        ddlContacts.disabled = true;
    }
    ddlContacts.add(element, 0);    
    ddlContacts.selectedIndex = 0;
}

Gadget floating on desktop showing contacts

I've gotten a few requests from friends who want their Outlook 2007 contacts to show up in the gadget. Since this isn't supported directly by the Vista Sidebar Object Model I'd have to do the Outlook 2007 interop my self. I assume this wouldn't be too hard, but I haven't had time to figure this out yet. Drop me a comment if you have any good resources on how to read the Outlook 2007 address book from script. However, if you're running Outlook 2007 I have something far cooler up my sleeves for the next part of this series on how to make the most fun out the SMS library!

The download link points to the Windows Live Gallery site, so if you download and like the gadget please rate it. Feel free to post any comments, suggestions, questions or feedback.

This blog post is the first one in a series of posts covering how to send free SMS messages using the Ung1881 web site. This first post discuss how to sign into a "Forms Authentication" protected ASP.NET web site, store an authentication cookie, and programmatically post web forms. Even if you're not interested in the free SMS messages you might still find the article interesting. The next part will be on how to use the .NET Class Library in a Windows Vista Gadget.

Unlimited free SMS messages, exposed as a .NET Class Library… Sounds to good to be true? Well, It's not, but as with everything else that's free (except Open Source?) it has a catch.  You can only send messages containing 130 characters. The last 30 characters are reserved for commercials. The good thing is that you can send as many messages as you want, and your own number show up as the sender. The service is offered by "Opplysningen 1881"  (Norwegian Number Enquiry) through their new portal "Ung1881", a page aimed at young people. In order to use their SMS service you need to be a have a Norwegian social security number, and a phone number. They need your social to do a lookup and verify that you're a real person. Even though you might not be able to register for an account at "Ung1881" you might still find the code and article useful since the concepts apply for any web application.

I got interested in the "Ung1881" after Håvard pointed me to it some weeks back. After doing some re-search it turned out someone had written a Mac OSX Widget letting you send SMS messages directly from your Mac desktop. My immediate idea was to port this widget to the Windows Vista Sidebar, but after looking at the JavaScript code of the widget I soon realized this was a bad idea. The Mac OSX Widget is depending on a third party server doing the screen scrapping server side, so all your SMS messages (including your username and password) are sent through a third party using HTTP GET like this: http://www.theretard.net/smss.pl?u=username&p=password&n=number&m=message. I don't know the guys behind theretard.net, but there's no way I'm trusting them with my username, password and every SMS message I ever send. Just imagine the password harvesting possibilities! On top of this they don't even use HTTPS for communication.

I decided I had to write a .NET Assembly wrapping the "Ung1881" service, so that I could re-use the functionality in other applications, like a Windows Vista Sidebar Gadget, a console application, Outlook 2007, PowerShell etc.

The technique of accessing web sites programmatically is commonly refereed to as  screen scrapping. Since the Ung1881 portal doesn't offer any kind of programming interface, you need to tap in to it at the HTTP level, and "pretend" that you're a regular user accessing the page with a browser. Since you're depending on the actual HTML structure page you're application might become unstable, and if the owner of the source you're scrapping change their HTML it might break your application. You also need to be careful that you're not violating copyright regulations, by for instance downloading weather information and displaying it as your own. In the case of "Ung1881" terms don't say anything about "automatic access", and as long as you have a valid account they still get their 30 character commercials included in every SMS message you send. I don't think you'll get into trouble by using this code, but if you do don't blame me!

The "Ung1881" portal is running on the .NET-based Content Management System EPiServer, and uses ASP.NET Forms Authentication to authenticate users on the portal. Forms Authentication normally works by using an authentication cookie. When you logon the server authenticates your username and password. If your credentials are valid, it issues a cookie your browser sends with subsequent requests to the site. So in order to wrap the SMS service in a C# class you basically need to write a "non visual" Web Browser. You need to make a request to their login page, use HTTP POST to post a username and password to the server and store the authentication cookie sent back in the response. On subsequent requests you need to attach the authentication cookie in order to access protected pages (like the send SMS page).

The first thing I did when implementing the "Ung1881" proxy class was to analyze the HTTP traffic going between server and client. There are several tools you can use to monitor network traffic at different levels. My preferred HTTP monitor is Fiddler. Fiddler act as a HTTP Proxy, so all you're HTTP requests are routed through Fiddler. Using Fiddler you can look at the raw requests, the headers, the posted form values etc. New in Fiddler v2.0 is support for HTTPS, which is excellent since the "Ung1881" portal is using HTTPS for secure communication. Another excellent tool for network monitoring is oSpy, written by Ole André Vadla Ravnås - a brilliant programmer, reverse engineer and in general a really nice guy!

The above screenshot shows all the HTTP traffic between Internet Explorer and the "Ung1881" web server. As you can see in the left column the site is quite "chatty" because of all the pictures, advertisements, script, style sheets etc. If you enter your username, password and hit the login button, and look at the request made to the URL https://www.ung1881.no/default____3.aspx you can figure out which form elements that are being posted to the server. The site contains quite a few form elements, but the interesting parts are the following:

Content-Disposition: form-data; name="defaultframework:login:tbxUsername"
myusername

Content-Disposition: form-data; name="defaultframework:login:tbxPassword"
mypassword

Content-Disposition: form-data; name="defaultframework:login:LoginButton.x"
0

Content-Disposition: form-data; name="defaultframework:login:LoginButton.y"
0

Content-Disposition: form-data; name="__VIEWSTATE"
dDw5NDE0MjMxMzc7O2w8ZGVmYXVsdGZyYW1ld29yazpsb2dpbjpMb2dpbk
J1dHRvbjtkZWZhdWx0ZnJhbWV3b3JrOnNlbmRzbXM6YnRuU2VuZDs+Pp5c
kvQYH64y3L+4/9ebcQzi7GmX

I've highlighted the names of the form elements. You could have figured out most of this just by looking at the HTML source, but I find it easier to use Fiddler. The thing that might not be too obvious just by looking at the HTML source, is what form value get posted when you click the login image button. The HTML fragment looks like this:

<input type="image" name="defaultframework:login:LoginButton" id="defaultframework_login_LoginButton" class="..." src="..." alt="" />

If you look at the HTTP POST values above you can see that there are two values posted back to the server when you click the login button, defaultframework:login:LoginButton.x and defaultframework:login:LoginButton.y. Both have the value 0. I took a few seconds before I figured what was happening, but apparently the HTML specifications says that <input type="image"> should post back the x and y values with the coordinates of where the user clicked the image. For accessibility reasons this is deprecated, and if you need x and y values from an image you should use an <imgemap> element instead. In order to confirm with the HTML standard the browser posts an x and y value back to the server.

Another important thing to note is that "Ung1881" is an ASP.NET application, and therefore is depending on the "__VIEWSTATE" form element. This hidden form value holds an encoded string representing the state of the application on the server. If we don't include this value in our scrapper the ASP.NET application can't figure out what state it's in, and how to process the request correctly.

If you look at the response sent back from the server you see that the server issues three cookies:

ASP.NET_SessionId=jnq5hh45zuuu0xyigc1jtm45; path=/

.EPiServerLogin=
6E1DBAC98D4073F956DA2000EBF122056E335441CCC7756F98B2
A229387EC47E446701A29
D36C4497553A5409F40322142C84B140E93C25CFC468C81
5B25CCC35648CE9B03C96XXXXXXXXXXXX; path=/;HttpOnly

ung1881.no=3568924299.20480.0000; expires=Sun, 25-Mar-2007 16:22:15 GMT; path=/

The interesting part is the .EPiServerLogin-cookie which is the authentication cookie. By adding this cookie to my subsequent requests, the server can tell that you're an authenticated user.

Now that we know what's going on when login into the page it's time to send an SMS message. I click the "Send SMS" link on the page, which takes me to the following URL: https://www.ung1881.no/Templates/SMS____24.aspx. I enter a phone number and message, and hit the button to send the message. The requests gets picked up by Fiddler, and by analyzing the request I figure out which form elements I need to post to the server in order to send a message:

Content-Disposition: form-data; name="defaultframework:_ctl2:Smssend:txtPhonenumber"
myNumber

Content-Disposition: form-data; name="defaultframework:_ctl2:Smssend:txtText"
myMessage

Content-Disposition: form-data; name="defaultframework:_ctl2:Smssend:butSend.x"
46

Content-Disposition: form-data; name="defaultframework:_ctl2:Smssend:butSend.y"
9

Content-Disposition: form-data; name="__VIEWSTATE"
*LARGE CHUNK OF STATE*

So after analyzing the application I now know the following about the communication between browser and server:

  • The login URL is: https://www.ung1881.no/default____3.aspx
  • The username form element is named: defaultframework:login:tbxUsername
  • The password form element is named: defaultframework:login:tbxPassword
  • The login button posts two values: defaultframework:login:LoginButton.x and defaultframework:login:LoginButton.y
  • The server issues an authentication cookie named .EPiServerLogin
  • The send SMS URL is: https://www.ung1881.no/Templates/SMS____24.aspx
  • The number form element is named: defaultframework:_ctl2:Smssend:txtPhonenumber
  • The message form element is named: defaultframework:_ctl2:Smssend:txtText
  • The send SMS button posts two values: defaultframework:_ctl2:Smssend:butSend.x and defaultframework:_ctl2:Smssend:butSend.y

Now that I know everything I need to know about the form elements It's time to write a C# class wrapping the site. The code is fairly well commented, so I won't describe it in detail. The key classes involved in the scrapper are the HttpWebRequest, HttpWebResponse, CookieContainer, StreamReader and StreamWriter classes. Another interesting part of the code is the private GetViewState method which extracts the view state of the page so that you can post it back to the server.

 

// Copyright (c) 2007, Jonas Follesø
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the Jonas Follesø nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY Jonas Follesø ``AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL Jonas Follesø BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

using System;
using System.IO;
using System.Net;
using System.Text;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Security.Authentication;

namespace Ung1881
{
    /// <summary>
    /// Proxy class wrapping the Ung1881 site for free SMS messaging.
    /// </summary>
    public class Ung1881Proxy
    {
        /// <summary>
        /// Variable used to store the authentication cookie.
        /// </summary>
        private CookieContainer cookies;

        /// <summary>
        /// Variable used to store the base uri of the page.
        /// </summary>
        private string baseUri = "https://www.ung1881.no/";

        /// <summary>
        /// Default constructor.
        /// </summary>
        public Ung1881Proxy()
        {
            cookies = new CookieContainer();
        }

        /// <summary>
        /// Login on Ung1881 using username and password.
        /// Authenticates against the site and keeps the auth cookie for next request.
        /// </summary>
        /// <param name="username">Username used to logon.</param>
        /// <param name="password">Password used to logon.</param>
        public void Login(string username, string password)
        {
            //Validate arguments.
            if (username == null || username.Length == 0)
                throw new ArgumentException("You must provide a username!", "username");

            if (password == null || password.Length == 0)
                throw new ArgumentException("You must provide a password!", "password");
            
            string loginUri = baseUri + "default____3.aspx";

            // Perform the first http request against the asp.net application login site.
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(loginUri);

            // Get the response object, so that we may get the session cookie.
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            // Populate the cookie container.
            request.CookieContainer = cookies;
            response.Cookies = request.CookieContainer.GetCookies(request.RequestUri);            

            // Read the incoming stream containing the login dialog page.
            StreamReader reader = new StreamReader(response.GetResponseStream());
            string loginDlgPage = reader.ReadToEnd();
            reader.Close();            

            // Extract the viewstate value from the login dialog page. 
            // We need to post this back, along with the username and password
            string viewState = GetViewState(loginDlgPage);

            // Build postback string.
            // This string will vary depending on the page. The best way to find out what your postback 
            // should look like is to monitor a normal login using a utility like Fiddler.
            string postback = String.Format("__VIEWSTATE={0}&defaultframework:login:tbxUsername={1}" +
                                            "&defaultframework:login:tbxPassword={2}" + 
                                            "&defaultframework:login:LoginButton.x=0&defaultframework:login:LoginButton.y=0",
                                            viewState, username, password);


            // Our second request is the POST of the username / password data.
            request = (HttpWebRequest)WebRequest.Create(loginUri);
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.CookieContainer = cookies;            

            // Write our postback data into the request stream
            StreamWriter writer = new StreamWriter(request.GetRequestStream());
            writer.Write(postback);
            writer.Close();

            reader = new StreamReader(request.GetResponse().GetResponseStream());
            loginDlgPage = reader.ReadToEnd();
            reader.Close();

            int index = loginDlgPage.IndexOf("Logg ut", StringComparison.OrdinalIgnoreCase);

            if (!CheckAuthenticationCookies() || index == -1)
            {
                throw new AuthenticationException("Unable to authenticate user. Check your username and password.");
            }            
        }

        /// <summary>
        /// Method sending a new SMS message trough Ung1881.
        /// </summary>
        /// <param name="phoneNumber">The phone number of the receiver.</param>
        /// <param name="message">The message to send.</param>
        /// <returns>True if the message was sendt sucsessfully.</returns>
        public void SendSms(string phoneNumber, string message)
        {
            //Validate arguments
            if (phoneNumber == null || phoneNumber.Length == 0)
                throw new ArgumentException("You need to provide a phone number!");

            if (message == null || message.Length == 0)
                throw new ArgumentException("You need to provide a message!");

            //Check that we have an authentication cookie.
            if (!CheckAuthenticationCookies())
                throw new AuthenticationException("User not authenticated. Call Login first!");

            //our third request is for the actual webpage after the login. 
            string smsUrl = baseUri + "/Templates/SMS____24.aspx";
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(smsUrl);
            request.CookieContainer = cookies;

            //and read the response
            StreamReader reader = new StreamReader(request.GetResponse().GetResponseStream());
            string page = reader.ReadToEnd();
            string viewState = GetViewState(page);

            string postback = String.Format("__VIEWSTATE={0}&defaultframework:_ctl2:Smssend:txtPhonenumber={1}" +
                                            "&defaultframework:_ctl2:Smssend:txtText={2}&defaultframework:_ctl2:Smssend:butSend.x=0" +
                                            "&defaultframework:_ctl2:Smssend:butSend.y=0", viewState, phoneNumber, message);

            reader.Close();

            request = (HttpWebRequest)WebRequest.Create(smsUrl);
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.CookieContainer = cookies;

            //Write our postback data into the request stream
            StreamWriter writer = new StreamWriter(request.GetRequestStream());
            writer.Write(postback);
            writer.Close();

            //Execute the request and read the response.
            reader = new StreamReader(request.GetResponse().GetResponseStream());
            page = reader.ReadToEnd();
            reader.Close();

            //Verify that the message was sent.
            if (!page.Contains("SMS sendt"))
            {
                throw new Ung1881Exception("Unable to send SMS message. Unknown error.");
            }            
        }

        /// <summary>
        /// Check if the user is authenticated.
        /// </summary>
        /// <returns>True if the user is authenticated.</returns>
        private bool CheckAuthenticationCookies()
        {
            bool authenticated = false;

            //Check that we have cookies.
            if (cookies != null)
            {
                //Check all cookies for the EpiServerLogin cookie.
                foreach (Cookie cookie in cookies.GetCookies(new Uri(baseUri)))
                {
                    if (cookie.Name != null && 
                        cookie.Name.Equals(".EPiServerLogin", StringComparison.OrdinalIgnoreCase))
                        authenticated = true;
                }
            }
            return authenticated;
        }

        /// <summary>
        /// Extract the viewstate data from a page.
        /// </summary>
        /// <param name="aspxPage">The raw HTML of the page.</param>
        /// <returns>Thew viewstate data of the page.</returns>
        private string GetViewState(string aspxPage)
        {
            Regex regex = new Regex("(?<=(__viewstate\".value.\")).*(?=\"./>)", RegexOptions.IgnoreCase);
            Match match = regex.Match(aspxPage);
            return System.Web.HttpUtility.UrlEncode(match.Value);
        }
    }
}

To test the class I've created a simple console application accepting a username, password, number and message as it's argument. Using the console application you can send SMS messages by typing the command: "SMS username password number message". If you add the folder containing the .EXE to your environment path you can send SMS messages from any command prompt.

 

// Copyright (c) 2007, Jonas Follesø
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the Jonas Follesø nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY Jonas Follesø ``AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL Jonas Follesø BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

using System;
using System.IO;
using System.Net;
using System.Text;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Ung1881;
namespace ConsoleScraper
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                //Check that we have at least four arguments (username, password, number, message)
                if (args.Length < 4)
                {
                    Console.WriteLine("Usage: SMS username password number message");
                }
                else
                {
                    //Extract variables from arguments.
                    string username = args[0];
                    string password = args[1];
                    string number = args[2];
                    string message = string.Empty;

                    //Build up the message.
                    for (int i = 3; i < args.Length; ++i)
                    {
                        message += args[i];

                        //Add space if this isn't the last word of the message.
                        message += (i == args.Length - 1) ? string.Empty : " ";
                    }

                    Console.WriteLine("Sending message \"{0}\" to number {1}", message, number);

                    //Send the message.
                    Ung1881Client client = new Ung1881Client(username, password);
                    client.SendMessage(number, message);                    
                    Console.WriteLine("Message \"{0}\" sent to number {1}", message, number);
                }
            }
            catch (Exception ex)
            {
                //Simple exception handling.
                Console.WriteLine(ex.ToString());
            }
        }
    }
}

So that's about it. A simple C# library allowing you to send unlimited free SMS messages through "Ung1881". You can choose to either download the compiled binaries or the source code. In the next part of this article/post I'll discuss how to use the library in a Windows Vista Sidebar Gadget.

If you have any questions, comments or bugs, or find the library useful, please drop me a comment!

In the VS2005 beta and ctp releases the default behavior was that new projects weren’t saved when you created the project. This enabled you to easily create a simple web app or any other VS2005 project, do some testing and discard the files. That way your project folder didn’t get filled up with “Project 1”, “Project 2” and so fourth. Before this functionality came along in VS2005 you would typically use SnippetCompiler to do this kind of “testing”. 

In the final release of VS2005 this isn’t the default behavior, and I’ve been asked a couple of times if Microsoft removed this feature. No, they didn’t. If you go to the Tools – Options – Project and Solutions settings, and uncheck “Save new projects when created” you get this behavior back.

It’s been about two weeks since I received my iPod 60 GB with video functionality. The device is just amazing. The video quality is great. I guess the only bad thing to say about the player is battery life when playing video and format support.

CopytoipodSince I have a Windows Media Center Computer I’ve been looking at different ways to integrate recorded TV on the iPod. Tony Northrup over at Microsoft wrote an article on how to copy recorded TV shows from Media Center to iPod. I discuss two approaches, one using MyTV ToGo, which is a commercial product and one tying together free tools.

The free approach is the most interesting one. He basically integrates DVRMSToolbox, Vidora iPod Converter and iTunes Library Updater together using a batch file. The batch file is integrated into the Windows Shell as a context menu item when you right click DVR-MS files.

Since I don’t have the iPod connected to the Media Center I did some modifications to the batch file. Instead of using the iTunes Library Updater I copy the output file to a shared directory on the Media Center. Then on personal laptop (I have one for work and one or play) I can add the files to my iPod.

If you want a step by step by step guide on how to do this check out Tony’s article.

 

The company I work for, Abeo, have standardized on IBM Thinkpad computers for their consultants. I currently have a IBM T43p, which is an awesome computer. The only disadvantage of using IBM Thinkpads is that they don’t have a special Windows key. 

The Windows key is used for many timesaving shortcuts, such as:

  • Winkey + Pause = display the Systems Properties page
  • Winkey + R = display the Run dialog box
  • Winkey + M = minimize all windows
  • Winkey + D = minimize all windows. Press again and desktop apps reappear.
  • Winkey + Shift + M = undo minimize all windows
  • Winkey + F1 = starts Windows Help (F1 by itself brings up Help in the current application)
  • Winkey + E = start Explorer
  • Winkey + F = start Find
  • Winkey + F + CNTL = start Find Computer
  • Winkey + B = Sets focus on the task bar
  • Winkey + TAB = cycle through taskbar buttons
  • Winkey + BREAK = display Systems Properties panel
  • Winkey + L = lock Desktop

The solution to the problem is to use a technique called keyboard remapping. Basically what you do is that you map one key to another. I’ve remapped “Caps Lock” to act as my “Left Winkey”. Who uses “Caps Lock” anyway? Well, the guy who thought me to program years ago used “Caps Lock” instead of shift..! But that’s a different story...   

Key remapping in Windows can be achieved simply by writing some information to the registry. The cool thing is that you don’t have to write these registry settings by hand. A guy called randy, over at http://www.randyrants.com/, have written a tool called SharpKeys. This tool allows you to configure your keyboard remapping in an easy manner. A screenshot of my current remapping is shown below:

Sharpkeys screenshot

Update: You can do some keyboard remapping in the default IBM Thinkpad software. How ever, it doesn’t let you remap all the keys. You only remap left and right shift, left and right ctrl, alt and alt gr to the Windows key. I guess the most reasonable choice would be the right ctrl, at least if you’re running Virtual PC and have to use left ctrl + alt instead of alt gr.

Happy remapping!

 

<March 2010>
SunMonTueWedThuFriSat
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910