Wednesday, December 29, 2010

Reviewing and renewing resolutions

My career

I'm still working on the same projects as I was last year: Firestation Antwerp and Ghent. This year we did not build a lot of brand new things, but we have added a decent amount of new functionalities. Next to that there were a bunch of bugs to fix and technical debt to pay off. I learned a lot from the mistakes we made and refactoring makes you really think about what good and clean code should look like.

In 2011 I will still be spending time on Firestation Antwerp and Ghent. There is a hazy bright light on the horizon though, chances are there is a new interesting challenge ahead.

This year I had some fun side-challenges. I gave internal technical sessions on ASP.NET 4 & ASP.NET AJAX, something I enjoyed doing more than I thought. I also passed the MCTS 70-536 exam, which I didn't enjoy studying for that much. In 2011 I want to pass at least one MCTS ASP.NET exam, and give more technical sessions.

Blog

I have written 62 posts this year. Not as much as I would have liked to. There are several reasons I didn't produce more content. I have had a technology hiatus this summer, because I was just too busy with other life stuff. Next to that, I have been working on a side-project and have been studying for the MCTS 70-356 exam. A lot of excuses, but I plan to make up for it in 2011.

I am pretty satisfied with the qualtiy I produced this year, although there is a lot of room for improvement. I like to think a good metric for quality is the number of visitors and retweets. I got double the traffic compared to last year, which makes me feel a little warm inside.



This year I mainly blogged about Webforms (refactoring), ASP.NET AJAX, the Bing API, TechEd, IE9 and HTML5. In 2011 I plan to continue to focus on Microsoft and the web. I'm still an MVC and WebMatrix novice, which needs to change next year.

Community

Last year I planned on being more active on StackOverflow, but I failed miserably. I don't think I will be making this a goal this year. I'm just going to continue to go there for questions only.

I also planned on going to a big event in 2010, which turned out to be TechEd Europe. Seriously, I could hang around there an entire month.

In being part of the Belgian .NET community I was less successful. I have been talking a lot with other Belgian developers through blogs and Twitter, but I should attend more real-life events. With the DrinksWithDevs community Davy Brion is starting, I think I might be doing better this year.

Travelling

One of the goals I'm totally satisfied about.

Next to citytripping in Belgium, I was lucky enough to travel abroad 5 times this year: There are no plans for next year (yet), but I don't think I will be able to do much better.

Sport/Health

This is a new section in this year's report. Sport has become more and more important to me over the years. Next to going to the gym and running, I picked up boxing this September.

In the next year I want to focus more on conditioning and less on strength. It's hard to set a specific goal right now, because I haven't measured the speed and distance of my runs this year. For Christmas I got the Nike+ iPod gear, so that should help me to collect some data the following months.

Conclusion

This year had its ups and downs. Not a lot of exciting things happened at work, but 2011 should change that. I am overall content with the progress of my blog, although I think I should do better next year. I should be very satisfied with the travelling I did this year, I have spent more than a month abroad! I think I improved my health noticeably this year, I hope I stay injury-free and can put enough effort in to keep on improving my conditioning.

All by all 2010 was a good year and I hope 2011 will be at least as good. And to be honest, I don't mind not being able to accomplish all goals, because the love of my family and friends compensates a lot. That was cheesy, right?

How was your year?

Monday, December 27, 2010

Format JavaScript with the IE9 developer tools

One of the new features in the IE9 developer tools Giorgio Sardo demoed at TechEd Europe, is the Format JavaScript tool. This tool can be very useful when you want to reverse engineer a minified script.

You can find this feature in the toolbox on the Script tab.


This is how jquery.min.js looks after formatting.


This feature is not available in the public beta (9.0.7.9360.16406), but should be available in the latest platform previews.

Edit: This feature is in the IE9 RC!

Sunday, December 26, 2010

HTML5: Exception handling with the Geolocation API

In my previous post on the Geolocation API I passed in a PositionErrorCallback to the geolocation.getCurrentPosition() method. When I received this callback I displayed a generic message informing the user something went wrong. In real-world scenarios you probably want the message to be more specific. You might also want to call a specific fallback method depending on what went wrong.

This is where the PositionError argument of the PositionErrorCallback comes in handy. This object has two properties: code and message.

The code property can return three codes:
  • 1: PERMISSION_DENIED
  • 2: POSITION_UNAVAILABLE
  • 3: TIMEOUT
The message property returns a string describing what went wrong. Be careful, this property is primarily intended for debugging!

Example

The codesnippet below only shows the part where I am handling the PositionErrorCallback. You can find the demo and full source here.

function onError(error){
    var content = document.getElementById("content");        
    var message = "";
    
    switch (error.code) {
        case 0:
            message = "Something went wrong: " + error.message;
            break;
        case 1:
            message = "You denied permission to this page to retrieve a location.";
            break;
        case 2:
            message = "The browser was unable to determine a location: " + error.message;
            break;
        case 3:
            message = "The browser timed out before retrieving the location.";
            break;
    }
    
    content.innerHTML = message;
}

Top 5 popular posts of 2010

Today I have spent a few hours evaluating this year's analytics of my blog. In total I posted 59 entries this year, but in this post you will only find the 5 most popular, plus the ones that I liked writing a lot but failed to make it to the top 5.

The most popular posts of 2010

1. Cannot start Service from the command line or debugger.: The most popular post of 2010, almost all traffic was completely driven by search engines. In this post I share a trick that makes it easier for our team to debug Windows services. Next to the trick our team uses, I also share some alternative (Microsoft) approaches to this issue.

2. Customizing Telerik RadGrid tooltips: Looks like a lot of people are not fond of the default RadGrid tooltips, or they are searching for a way to localize the tooltips (which is not supported). In this post I show how you can customize the RadGrid tooltips and make the customization consistent through your webapplication using ASP.NET Themes.

3. Listening for UDP packets in a Windows service using an UdpClient: In this post you can find how to use an UdpClient in a Windows service to listen for UDP packets.

4. HTML5: The Geolocation API is scary (good): People definitely are curious for HTML5. Here I show an example of the HTML5 Geolocation API. I also search for documentation on the internals of the Geolocation API, but come home empty handed. I am still looking for good resources! You can also find a demo where you can test how accurate the Geolocation API is for your machine. Please let me know.

5. Switching with non-constant cases in C#: In this post I try to resolve Compiler Error CS0150 (A constant value is expected). The first option uses else-if statements and the second option uses a dictionary. The second option turns out to be the most safe and elegant.

My favorite posts of 2010

1. Webforms lessons learned the hard way Part 1 and Part 2: In these two posts I look back on what I have learned about Webforms in the past two years.

2. Webforms refactoring: Eliminating redundant eventhandlers using a dictionary to map controls: Something I have seen way too often, redundant eventhandlers in Webforms. In this post I use a few iterations to come up with a good solution. You should also check out the follow-up.

3. Building a tagcloud with jQuery and ASMX Webservices: This post demonstrates how you can create your own tagcloud using jQuery and good old ASMX Webservices.

Thank you so much for reading my posts this year! I will come to a more in-depth personal review of 2010 in a future post.

Sunday, December 19, 2010

HTML5: The Geolocation API is scary (good)

I read about the HTML5 Geolocation API in the Pro HTML5 Programming book a while ago, and decided to play with it on this lazy Sunday.

Using the Geolocation API to make a one-shot position request is very straight-forward. Get a reference to the navigator.geolocation object and call the getCurrentPosition() method, passing in at least a PositionCallback. In this example I'm also passing in a PositionErrorCallback. In the PositionCallback you can examine the properties of the position object. Here I am only using the latitude and longitude properties.

function showLocation(){                        
    if (navigator.geolocation){
        navigator.geolocation.getCurrentPosition(onSuccess, onError);
    } else {
        var content = document.getElementById("content");        
        content.innerHTML = "Geolocation is not supported by your browser!";
    }                
}
 
function onSuccess(position){
    var content = document.getElementById("content");        
    content.innerHTML = position.coords.latitude + ", " + position.coords.longitude;
}
 
function onError(error){
    var content = document.getElementById("content");        
    content.innerHTML = "Something went wrong..";
}

That's really easy, right? You can find the complete source and demo here.

The scary part

The privacy part isn't that scary, because the specs state that browsers must acquire permissions through a user interface. The scary part is, that it really works and is very accurate even though I'm on a desktop with no known hotspots nearby! After getting the results, I pasted them in Google Maps and they were only a few meters off. Why is it that while most geolocation services have been failing over the years, it suddenly works this good?

There is some documentation out there, but this documentation is very simplistic and doesn't touch the internals.

The Pro HTML5 Programming book lists which sources can be used.
A device can use any of the following sources:
  • IP address
  • Coordinate triangulation:
    • Global Positioning System (GPS)
    • Wi-Fi with MAC addresses from RFID, Wi-Fi and Bluetooth
    • GSM or CDMA cell phone IDs
  • User defined
FireFox lets the Google Location Services assist them.
If you consent, Firefox gathers information about nearby wireless access points and your computer’s IP address. Then Firefox sends this information to the default geolocation service provider, Google Location Services, to get an estimate of your location. That location estimate is then shared with the requesting website.

Feel free to share more good resources!

What is the outcome on your machine?

Check out the demo, paste the result in Google Maps and please let me know how accurate the results are for you.

Saturday, December 18, 2010

Programmatically disable UpdatePanels

In this post I'll show you how to programmatically disable all UpdatePanels in a page. I don't know in which scenario you would want to use this, but I had to use it to hack around an issue with the ReportViewer control. I'll save you the details, really.

To disable all the UpdatePanels, you need to set the EnablePartialRendering property of the ScriptManager to false. You can get a reference to the current ScriptManager by using the GetCurrent() method passing in a reference to the current page.
protected void Page_Init(object sender, EventArgs e) {
ScriptManager.GetCurrent(this.Page).EnablePartialRendering = false;
}
There is one gotcha: you need to set this property on the Page_Init event, otherwise an InvalidOperationException gets thrown.

Sunday, December 12, 2010

HTML5 selectors and jQuery

In my first post on the HTML5 javascript Selector API I wondered how the new methods querySelector() and querySelectorAll() would influence jQuery.

At the time, I couldn't find any information on the subject, but yesterday I found out that jQuery has been taking advantage of these new methods since version 1.4.3.

From the release notes..
The performance of nearly all the major traversal methods has been drastically improved. .closest(), .filter() (and as a result, .is()), and .find() have all been greatly improved.

These improvements were largely the result of making greater use of the browsers querySelectorAll and matchesSelector methods (should they exist). The jQuery project petitioned the browsers to add the new matchesSelector method (writing up a test suite, talking with vendors, and filing bugs) and the whole community gets to reap the excellent performance benefits now.




The above performance results specifically look at three very common cases in jQuery code: Using .closest() on a single DOM node, using .filter() (or .is()) on a single DOM node, and using .find() rooted on a DOM element (e.g. $(“#test”).find(“something”)).

Note that the the browsers shown are those that actually support querySelectorAll or matchesSelector – existing browsers that don’t support those methods continue to have the same performance characteristics.

Looks like it's not a bad idea to keep an eye on the release notes..

Friday, December 10, 2010

More accurate javascript execution time measurement with the msPerformance API

A cool feature of Internet Explorer 9 is the msPerformance API. This API helps you to accurately measure the performance of a webpage. A lot of developers have built their own performance measurement constructs over the years, based on the Date function, but the results of these constructs can be way off!

John Resig (jQuery inventor) has an in detail blogpost where he discovers where custom javascript execution time measurement goes wrong.
In Summary: Testing JavaScript performance on Windows XP and Vista is a crapshoot, at best. With the system times constantly being rounded down to the last queried time (each about 15ms apart) the quality of performance results is seriously compromised. Dramatically improved performance test suites are going to be needed in order to filter out these impurities, going forward.

Browsers know exactly how long it takes to load webpages and execute scripts. IE9 now makes it possible to consume this information through the msPerformance API.

If you are interested in performance marks of the document loading, you can read properties of the msPerfomanceTiming object. If you are, like me, interested in measuring execution time of a specifc function, you can use some functions of the msPerformance object. Have a look at the following codesnippet.

function runTest(){                
    var msPerformance = window.msPerformance;
    
    if (msPerformance){        
        msPerformance.mark("writeLoopBegin");
        
        for (var  i = 0; i < 50000; i++){
            document.writeln(i);
        }        
        
        msPerformance.markAndMeasure("writeLoopEnd", "writeLoopMeasure", "writeLoopBegin");        
        var res = msPerformance.getMeasure("writeLoopMeasure");
        
        alert(res + " ms elepased.");    
    } else {
        document.write("msPerformance isn't available in your browser.")
    }
}

The first thing you have to do is get a reference to the msPerformance object. To start measuring you need to call the mark function. After marking, you can run the code you want to measure. When that is done, you need to call the markAndMeasure function. Once the end is marked an measurement is finished, you can get the results by calling the getMeasure function.

See it in action here.

What about standards?

You probably noticed by the ms prefix that this isn't part of the standards yet. It does look like there are efforts being made by the W3C to get a performance measurement API into the standards though.

Is this something you have been waiting for?

Sunday, December 5, 2010

HTML5: Drawing images to the canvas gotcha

While I was playing with the Canvas API I came across a weird issue: I was trying to draw an image to the canvas, but the image failed to render very often.

Have a look at the source. Do you spot the problem?

<!DOCTYPE html>
<html>
    <head>
        <title>HTML5: Canvas</title>
        <script type="text/javascript">        
            window.addEventListener("load", draw, true);
            
            function draw(){                            
                var canvas = document.getElementById('canvas');
                var context = canvas.getContext('2d');    
 
                var img = new Image();
                img.src = "http://3.bp.blogspot.com/_0sKGHtXHSes/TPt5KD-xQDI/AAAAAAAAA0s/udx3iWAzUeo/s1600/aspnethomepageplusdevtools.PNG";                
                
                context.drawImage(img, 0, 0);                
            }            
        </script>        
    </head>
    <body>
        <canvas id="canvas" height="500" width="500">
            Looks like canvas isn't supported in your browser! 
        </canvas>
    </body>
</html>

It wasn't until I opened Firebug and saw an unhandled exception in the console that I discovered what was going on.
uncaught exception: [Exception... "Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIDOMCanvasRenderingContext2D.drawImage]" nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)" location: "JS frame :: file:///....html :: draw :: line 15" data: no]

Browsers load images asynchronously while scripts are already being interpreted and executed. If the image isn't fully loaded the canvas fails to render it. Turns out the weird issue, is pretty logical.

Luckily this isn't hard to resolve. We just have to wait to start drawing until we receive a callback from the image, notifying loading has completed.

<script type="text/javascript">        
    window.addEventListener("load", draw, true);
    
    function draw(){                                    
        var img = new Image();
        img.src = "http://3.bp.blogspot.com/_0sKGHtXHSes/TPt5KD-xQDI/AAAAAAAAA0s/udx3iWAzUeo/s1600/aspnethomepageplusdevtools.PNG";                
        img.onload = function(){
            var canvas = document.getElementById('canvas');
            var context = canvas.getContext('2d');    
        
            context.drawImage(img, 0, 0);        
        };            
    }                    
</script>

You can find the demo and source here.

Did you spot the problem in the first codesnippet?

HTML5: More on selectors

Last weekend I blogged on new addittions to the javascript Selector API: querySelector() and querySelectorAll(). These two new methods enable you to find elements by matching against a group of selectors. I only scratched the surface in the previous post, that's why you can find a few more examples in this post. These examples should demonstrate the power and ease of use of the new Selector API features. It's impossible to show you all of the selectors usages in just one post, that's why I strongly encourage you to have a look at the W3C Selectors specifications.



I experimented on the asp.net homepage using the IE9 developer tools.

Attribute selectors

Select all elements which have an attribute named title.

>>document.querySelectorAll('[title]');
[object] {
    length : 5,
    0 : http://www.asp.net/,
    1 : [object HTMLImageElement],
    2 : http://www.asp.net/get-started,
    3 : http://www.asp.net/downloads,
    4 : http://www.asp.net/rss/spotlight
}

Select all elements where the title attribute has the value set to Rss.

>>document.querySelectorAll('[title=Rss]');
[object] {
    length : 1,
    0 : http://www.asp.net/rss/spotlight
}

Select all elements where the href attribute is set to http://umbraco.org/ and where the target attribute is set to _blank.

>>document.querySelectorAll('[href="http://umbraco.org/"][target="_blank"]');
[object] {
    length : 1,
    0 : http://umbraco.org/
}

Select all elements where the href attribute contains umbraco.

>>document.querySelectorAll('[href*="umbraco"]');
[object] {
    length : 3,
    0 : [object HTMLLinkElement],
    1 : [object HTMLLinkElement],
    2 : http://umbraco.org/
}

Class selectors

Find the first element where the class is set to .search_box.

>>document.querySelector('.search_box')
[object HTMLInputElement] {
    jQuery1291484082884 : 1,
    align : "",
    border : "",
    hspace : 0,
    vspace : 0,
    accept : "",
    alt : "",
    checked : false,
    defaultChecked : false,
    defaultValue : "Search"
    ...
}

Id selectors

Find the first element with the id #WLSearchBoxInput.

>>document.querySelector('#WLSearchBoxInput')
[object HTMLInputElement] {
    jQuery1291484082884 : 1,
    align : "",
    border : "",
    hspace : 0,
    vspace : 0,
    accept : "",
    alt : "",
    checked : false,
    defaultChecked : false,
    defaultValue : "Search"
    ...
}

Pseudo classes

Select the first hyperlink that is being hovered over.

>>document.querySelector('a:hover')
http://umbraco.org/ {
    charset : "",
    coords : "",
    hash : "",
    host : "umbraco.org:80",
    hostname : "umbraco.org",
    href : "http://umbraco.org/",
    hreflang : "",
    name : "",
    pathname : "",
    port : "80"
    ...
}

Select the third child element from the first element with the class .welcom_nav.

>>document.querySelector('.welcome_nav:nth-child(3)')
    type : "",
    compact : false,
    currentStyle : [object MSCurrentStyleCSSProperties],
    runtimeStyle : [object MSStyleCSSProperties],
    accessKey : "",
    className : "welcome_nav",
    contentEditable : "inherit",
    dir : "",
    disabled : false,
    id : ""
    ...
}

As you can see searching for elements with native javascript has become a lot easier. I tried to show some examples which can be applied to real life scenarios. Examples based on more complex scenarios can be found in the W3C Selectors specifications.

What do you think?