Wednesday, June 25, 2008
Wednesday, June 25, 2008 5:56:33 PM (SE Asia Standard Time, UTC+07:00) (Enterprise)

I learn something new nearly every time I write code - whether in a small project or large.

I recently updated my online gallery component at http://www.58bits.com/otherblog/photos/home.aspx. One of my TODO: items was a rewrite of a VCR style pager I've used previously. What I wanted was a style like the one shown in the screen shot...pager similar to that used on many sites. I also wanted user friendly(ish), hackable URLs, with each URL truly representing a resource; resources that may have more than one representation. For example, what you see visually as a user visiting the site - is a page with either thumbnails or a preview on it. However if you're an RSS reader, or a slide-show plug-in, you'll be given an RSS/XML representation of the same resource.

So what did I inadvertently create by moving to the new pager style? A  RESTFul pager. By asking for pages using the HTTP GET verb (as opposed to my old VCR pager that relied on forms and POST - ok a bad move I know) - I now have URLs that look like this...

http://www.58bits.com/otherblog/photos/5cgg96ab3e6g/thumbnails/2/2x3/view.aspx

And I now have a good separation from the server implementation, and the client's perception of a resource via a cool URL, and one that won't change.

As an aside, I can also now do something intelligent with caching, telling the client whether the resource has been updated or not via ETags, last modified dates and HTTP 304 response codes, saving a ton of bandwidth while at the same time ensure that changes propagate.

I'm a newbie to REST as an architectural style and am currently reading a lot on the topic - but what I've found from my initial exploration is that if you've been programming the Web for a little while, you've been close to REST by default. Embracing the style to include other verbs (other than the ubiquitous GET) is not such a big step, and I'm looking forward to experimenting further.

Here's a link to an author that's produced a great presentation on RESTFul Web Services



| Comments [0] | | #  
Monday, June 23, 2008
Monday, June 23, 2008 3:58:33 PM (SE Asia Standard Time, UTC+07:00) (General)

Hong Kong airport is now officially my favorite airport in the world. The Airport Express train in and out of town is a breeze. The food court in departures is large and comfortable.

And best of all free airport-wide WiFi that really works. Bangkok and London could to take a page from HK's book of good service. With an airport like this - going to the airport is fun - you can shop, get some work done, relax and then be on your way.

Just me and my ThinkPad T61p after a great weekend in Hong Kong.

IMG_2135



| Comments [0] | | #  
Thursday, June 19, 2008
Thursday, June 19, 2008 6:38:50 AM (SE Asia Standard Time, UTC+07:00) ()

UPDATE: Sun Tests Social Networking Toolkit

If I could design the future of social networking it would look like this...

I'd have a platform... some kind of service or software platform, from within which I could blog, twitter, chat and link to the people I know. I'd be able to choose exactly what information I wished to publish and when, and whether that information was published to just my friends, or to the world.

I'd be able to host the platform anywhere I choose. I could pay for it, or it might be free. If I paid for it - I'd want total control over where and how any advertising was allowed from within or outside the platform.

Imagine taking the best of LinkedIn, a decent blogging engine, something twitterish, a good chat client, a good media sharing platform for photos and videos. Add a pinch of social bookmarking - and wrapping all of that up into a very cool platform that I can use to represent me and those I choose to interact with in the online world. A sort of Bittorrent-ish, Groove-ish application for society. Goodbye MSN Messenger, Yahoo Messenger and Skype, goodbye to all of the walled garden social networking sites - and hello to my own little neighborhood in cyberspace.

The end of walled gardens like Facebook and other social networking sites is actively being discussed. What's missing is the glue in standards and software to bring together an alternative. The big guys like Google, Microsoft, and Yahoo want to try and grab on to this and hold on to it for its obvious potential in targeted marketing and advertising revenue.

I hope that doesn't happen. I hope we're each able to grab on to it, to control it and to use it to build new communities and socially meaningful ways of communicating with the world.



| Comments [0] | | #  
Saturday, June 14, 2008
Saturday, June 14, 2008 9:16:05 PM (SE Asia Standard Time, UTC+07:00) (C# | Utilities)

I know Jeff Atwood is a fan of this, and I'm surprised it's not made it on to Scott Hanselman's 2007 Ultimate Developer and Power Users Tool List for Windows tools list yet.

RegexBuddy is a brilliant tool and a great way to learn regular expressions. The documentation and introduction to regex is worth the price of admission alone.

regexbuddy
  (click to enlarge)

The expression tree view in the lower window practically talks to you as you build up and test your expressions. The expression to the right will match any incoming Url to myabsolutepath/subdir that begins and ends with either:

myabsolutepath/subdir
myabsolutepath/subdir/

or

myabsolutepath/subdir/*.aspx
myabsolutepath/subdir/*.ashx

I love this application.



| Comments [0] | | #  
Saturday, June 14, 2008 8:58:47 PM (SE Asia Standard Time, UTC+07:00) (Other Tech)

I like Windows Vista - it's a cool and stable OS. But it's taken me a while to get it to boot fast, and stop thrashing my disks to death. Windows Search, automatically scheduled items like Disk Defragmenter and Windows Defender and the biggest culprit - Superfetch, all put a heavy load on boot time and run time disk activity.

I tend to keep things pretty well organised and never really needed a desktop search engine and so I disabled Windows Search (the search feature on the start menu will still find program menu items - which is incredibly useful). I don't mind waiting a second or two for an app to load either and usually leave my frequently used apps running anyway - and so don't really want SuperFetch creating the 300,000 plus I/O events it records at system startup (watch it using Process Monitor from SysInternals). I also keep all my data on a separate volume from the OS - and so will manual defrag the OS disk once every couple of months. And I use the Complete PC Back up feature of Vista Busines/Ultimate to image the OS volume - giving me my own restore points - so I turn off restore points as well (Acronis True Image would be another good choice).

Here's a great article that just about covers it all on how to tune-down your Vista setup so that boot times and disk activity return to normal - Beginners Guides: Stopping Vista From Thrashing Hard Disks to Death.

Lone blogger 1 - Windows Vista 0



| Comments [0] | | #  
Saturday, June 14, 2008 8:09:49 PM (SE Asia Standard Time, UTC+07:00) (ASP.Net | CSS/XHTML)

I have a lot of respect for experienced CSS/XHTML designers having lived through two medium size projects that both had accessibility and XHTML Strict requirements - it was tough going. We survived the Peekaboo Bug, the Guillotine Bug, and the Duplicate Characters Bug to name a few.

I recently updated the design of my blog and my photo gallery component. Trying to keep the site IE6 compatible brought back painful memories. Thanks to this kind blogger at 456 Berea St - I managed to squash the last CSS bug in the layout - a problem I was having with space appearing between <li> items in a list that contains block level elements. I was kind of surprised to see this in IE7. The block element in this case was an <a> tag - and needed to have a width or height set in order to close up the gap between the containing <li>s; a very common layout for creating hover effects on menu items in <ul> lists. Sigh.

Lone blogger 1 - IE6/IE7 0



| Comments [0] | | #  
Sunday, June 08, 2008
Sunday, June 08, 2008 12:35:26 AM (SE Asia Standard Time, UTC+07:00) (C#)

I needed an undo stack today - but wanted it to behave like a queue when it was full, dropping the oldest items in the collection to make room for new ones. Found two posts - Undo Functionality with a Limited Stack, and also a reference to an identically named collection called LimitedStack here. 

Was initially thinking of simply writing a wrapper over an array of objects, shifting items along as new ones were added, but using a linked list is a clever solution, as it provides the queue like behavior needed without out any extra code via RemoveFirst() and RemoveLast().

using System;
using System.Collections.Generic;

namespace DotBits.Gallery.Builder.Objects
{
    [Serializable()]
    public class UndoStack<T> : LinkedList<T>
    {
        private int _maxItems;

        public int MaxItems
        {
            get 
            {
               return _maxItems; 
            }
            set
            {
                while (this.Count > value)
                {
                    this.RemoveFirst();
                }
                
                _maxItems = value;
            }
        }

        public UndoStack(int max)
        {
            _maxItems = max;
        }

        public T Peek()
        {
            return this.Last.Value;
        }

        public T Pop()
        {
            LinkedListNode<T> node = this.Last;
            this.RemoveLast();
            return node.Value;
        }

        public void Push(T value)
        {
            LinkedListNode<T> node = new LinkedListNode<T>(value);
            this.AddLast(node);

            if (this.Count > _maxItems)
            {
                this.RemoveFirst();
            }
        }
    }
}



| Comments [0] | | #  
Saturday, May 31, 2008
Saturday, May 31, 2008 6:31:49 PM (SE Asia Standard Time, UTC+07:00) (ASP.Net)

Visual Studio 2008 Professional shipped with the Visual Studio 2008 Team System unit test framework (which in Visual Studio 2005 was not available in the Professional version).

The test system is pretty cool - with excellent test code generating options and wizards. One really interesting feature is the ability to create tests for ASP.Net projects (file based, or application based). The tests created will be decorated as follows:

   1: /// <summary>
   2: ///A test for DemoTest
   3: ///</summary>
   4: [TestMethod()]
   5: [HostType("ASP.NET")]
   6: [UrlToTest("http://localhost/demo")]
   7: public void DemoTest()
   8: {
   9:     string input = "Boo";
  10:     string actual = "Boo1";
  11:     actual = input + "1";
  12:     Assert.AreEqual(input , actual);    
  13: }

 

Previously to the only way to test components in an ASP.Net application - especially one that depended on any custom configuration settings or configuration sections in the Web.config file - was to take a copy of all the required settings - and place them in an App.config file for your Unit Test project. Then using a test running framework like TestDriven.Net or NUnit - run the tests.

With the new Visual Studio 2008 test suite, you can simply use the Test Wizard to create the test, which will detect all the dependencies and create test methods that look like the one above. When run - the tests execute in the same processes as the referenced web application (and so use the same configuration settings).

If you want to debug your tests - you then have to attach the debugger to the either the development web server, or the IIS process that is hosting your local website.

Here's a link to an article that will show you how to do either - How to: Debug while Running a Test in an ASP.NET Solution.

However you have to re-attach the debugger to the process manually for every test run you want to debug, which is a drag. After googling for a while - I wasn't able to find an easy way to get F5 debugging that would automatically attach to the correct process (a command line option in the project maybe?). Still, the essence of the tests are to test assertions against your code and expected results so for a mature application test suite this isn't too big a problem. However for a TDD design approach - having to re-attach the debugger on each run is pretty inconvenient. Am I missing something?



| Comments [0] | | #  
Tuesday, May 27, 2008
Tuesday, May 27, 2008 2:31:26 PM (SE Asia Standard Time, UTC+07:00) (ASP.Net | Utilities)

Wow - Google and searchers were all over the "URI templates and hackable search engine friendly URLs" line in my short WPF post below, which means there's a lot of interest in URI templates.

I found this post on Creating a Template based URI very helpful. You DON'T have to be building a WCF service to use these. You MUST however include a reference to the System.ServiceModel.Web assembly in your project before you can use the System.UriTemplate type.

Scott Hanselman's presentation at MIX08 on MVC was also very helpful as well as it clarified many things (not to mention being hugely entertaining).

The URI Templates of .Net 3.5 don't have anything to do with REST - they're just a utility class that helps to bind and match templates and parameters to and from URIs. When combined with a URL rewriter they make it easy to present hackable URLs the world.  As Scott said in his presentation - the URLs in a browser window are effectively part of the UI - and so should be treated accordingly when possible.

So... mystore.com/clothing/shirts would be cool, as opposed to mystore.com/products.aspx?type=clothing&category=shirts



| Comments [0] | | #  
Saturday, May 24, 2008
Saturday, May 24, 2008 6:33:26 PM (SE Asia Standard Time, UTC+07:00) (Utilities)
While sprucing up my blog - I started looking for a code snippet plugin for Windows Live Writer - and Leo Vildosola's Code Snippet Plugin for WLW still appears to be a good choice. Like a lot of developers I use a 'dark theme' for Visual Studio and so I'm not sure that using the copy as HTML plugin from Colin Coller would work.
 

Here's an example of the WLW Code Snippet Plugin in action...

   1: /// <summary>
   2: /// Hash utility - pass the hash algorithm name as a string i.e. SHA256, SHA1, MD5 etc.
   3: /// </summary>
   4: /// <param name="input"></param>
   5: /// <param name="algorithm"></param>
   6: /// /// <param name="upperCase"></param>
   7: /// <returns>Hashed String</returns>
   8: public static string HashIt(string input, string algorithm, bool upperCase)
   9: {
  10:  
  11:     if (string.IsNullOrEmpty(input))
  12:         throw new ArgumentNullException("input");
  13:     
  14:     if(string.IsNullOrEmpty(algorithm))
  15:         throw new ArgumentNullException("algorithm");                        
  16:     
  17:     byte[] result = ((HashAlgorithm)CryptoConfig.CreateFromName(algorithm)).ComputeHash(Encoding.UTF8.GetBytes(input));
  18:  
  19:     StringBuilder myHexHash = new StringBuilder(64); //Maximum length required for SHA2-256, SHA1 or MD5
  20:  
  21:     string formatter = string.Empty;
  22:  
  23:     if (upperCase)
  24:         formatter = "{0:X2}";
  25:     else
  26:         formatter = "{0:x2}";
  27:  
  28:     for (int i = 0; i < result.Length; i++)
  29:     {
  30:         myHexHash.AppendFormat(formatter, result[i]);
  31:     }
  32:  
  33:     return myHexHash.ToString();
  34: }


| Comments [0] | | #