IE does something better than Firefox, hell freezes over
Like most web developers, I write markup and Javascript that will work on both IE and Firefox, and if I'm particularly ambitious, Chome and Safari. I've been writing a lot of Javascript lately, which has been a good learning experience but frustrating at the same time. I don't have the luxury of using jQuery on my current project -- I am pretty much restricted to Prototype for legacy reasons. I was in the throes of reconciling a piece of code that copied values from one set of input fields to another, then accessing the innerHTML property of the target fields' containing div. I was doing simple value assignments ($("textBox1").value = $("textBox2").value), and in IE everything worked like a peach. Then I tested in Firefox and, to my amazement, the target input fields remained blank, even though FireBug assured me that the values were in fact being copied. I was certain I was making a mistake somewhere in code, and spent an hour or so meticulously pouring over every line of Javascript, attempting to find the roadblock. In desperation, I turned to the Google in search of an answer. What I found surprised me enough that I felt compelled to write this post.
Firefox does not reflect dynamic DOM changes in the innerHTML property of a given DOM element.
This means that if you set the value of a text box to "123", then call the innerHTML property of the DOM element that contains the text box, the value of the text box according to innerHTML will appear to be whatever it was prior to your alteration. In practice, when the page posts back to the server, the value will actually be "123" and not what innerHTML reports, but the fact that Firefox ignores the change gives me yet one more gray hair.
To get around this glaring oversight, I had to use the setAttribute() method on the DOM input element:
$("textBox1").setAttribute("value", $("textBox2").value);
This accomplishes both tasks -- updating the actual input value and changing the innerHTML property accordingly.
You've won this round IE... you've won this round.
Print This PostRed Gate releases Reflector 6
Lutz Roeder scored major points with developers the world over when he released his .NET Reflector software, a tiny package of TNT that lets the user examine compiled .NET assemblies, and even disassemble them (for debugging purposes). I know it's a tool I couldn't live without. I've used it countless times to examine APIs of core .NET libraries, as well as third party, ill-documented assemblies. (What? No documentation? Perish the thought!) In 2008, Red Gate acquired the rights to enhance and publish reflector, and so their first polished incarnation has wandered into the wild. .NET Reflector 6 is still free, but an optional "pro" version may be purchased for a paltry $195.00. Reflector has been upgraded to support the new .NET 4.0 framework, and both versions come with Visual Studio integration. Reflector Pro includes the ability to decompile from within Visual Studio, and debug step-through capabilities as well. (You know, for those times when you're certain that Microsoft has screwed something up in their base class libraries because your own code is pristine.) Add-ins for Reflector can be found on the Reflector Codeplex site in case the gun just isn't big enough for you out-of-the-box.
Print This PostAmbiguous match really is ambiguous in ASP.NET
I just love days of lost productivity. You know, the ones where you pine away at some problem, retracing every change you made, every source control update you performed, attempting to track down the offending bug in code. Days like yesterday, for example. I was working on a fairly nondescript ASP.NET web page, but every time I would attempt to run it I would get the following error:
Parser Error
Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.
Parser Error Message: Ambiguous match found.Source File: /Default.aspx Line: 1
The only thing that is typically on Line 1 of any ASP.NET web page is the Page declaration, which specifies the CodeBehind and Inherits properties, so naturally my first thought was that perhaps the class name for the page conflicted with another class in the same namespace. But this was an erroneous assumption, and after renaming the file several times I decided that was probably not the case.
After a few hours of searching, I realized that I had a button on my page declared something like this:
<asp:Button ID="cancel" runat="server" Text="Cancel" />
and an event on the same page (in CodeBehind) declared like this:
public event EventHandler Cancel;
As it turns out, when ASP.NET parses a page's controls, it does so in a case insensitive manner, which means that the two "cancel" properties (a button is really a protected property declared in the designer) conflict.
This, of course, is completely contradictory, since the code will actually compile (case matters; there should be no name conflict) and only crashes at runtime. This reeks of FAIL, especially since the whole point of ASP.NET is to make web pages more "object-like".
All the more reason to use MVC.
<asp:Button ID="cancel" runat="server" Text="Cancel" />
Best IE 6 smack down. Ever.
A friend sent me a link to this website, which has a disclaimer and the bottom that wins the gold in two categories: 1) side-splitting humor, and 2) caustic diatribe against inferior technology. I reprint it here in its full glory.
Print This Post"Hi, if you are coming to this site via Internet Explorer 6, you might not be getting the best experience possible. Honestly, I can't even begin to think about what your entire experience on the internet must be like? (...probably like riding a bike on the highway while cars blow by you on their way to Costco to get gallons of mayonnaise and 60-inch plasma TV's). How will you ever be able to use this website?????? You wont. You're an asshole and your browser is an asshole. So look, I'm going to be honest: I kind of hate you. BUT we c-a-n make this work. Here is what I am going to need you to do: fire up your Toshiba ShitBook© that weighs about 45 pounds, wipe the Cheeto dust off the screen, download Safari, delete Internet Explorer from your computer, punch yourself in the face, and get me a pulled pork sandwich."
NUnit assertions and constraints cheat sheet
I'm pouring through the NUnit documentation to get a better grasp on the robust unit testing API. I tend to learn quickly if I reproduce whatever I read (whether in written form, in passing conversation, with diagrams or drawings, etc.), so I decided to compile the NUnit assertions and constraints into a single "cheat sheet" for quick reference. You can download it here, if you'd like. If you find any errors, please shoot me an email (my email address is at the bottom of the cheat sheet).
Print This PostThe cake is not a lie with MVC and JSON
Ever since Google Maps showed us that rich internet applications were not only possible but pretty damn cool, developers have been striving to streamline the process of communicating with web application servers without refreshing the browser. Initially this was done by writing JavaScript to work directly with the XMLHttpRequest object; but this was tedious and not at all elegant. Then some smart folk came up with the Prototype JavaScript framework and made everyone's lives easier by abstracting AJAX functionality, making it easier to work with. jQuery dazzled developers by simplifying the process even more. XML began leaving a bad taste in everyone's mouths, so other smart people figured out that instead of passing tagged markup data back and forth, these JavaScript frameworks could transmit and receive JSON. Because JSON is the native way to serialize JavaScript objects, and because it is significantly less bloated than XML, it was the natural choice for future rich internet applications.
Now, I have a real passion for simplicity and elegance, so any web application framework that makes AJAX easier to write and maintain is my friend. Since I've been learning ASP.NET MVC, I decided to see how it stood up to the challenge. Like most everything else in MVC, AJAX/JSON support is cake, not a lie. A JSON driven AJAX call in MVC consists of:
- the page that makes the AJAX call, which sends and/or receives data;
- a custom MVC action on a new or existing MVC controller that will handle the AJAX call, do the heavy data lifting, and return a result; and
- a custom MVC Route that maps to the controller/action in Global.asax
It's easiest to start with the controller/action, so here we go.
There are a few things to note here, namely the return type of the Authorize() method (JsonResult instead of ActionResult), and the method called to render the data (Json() instead of View()). Also, while any pre-defined, strongly typed object could be passed into the Json() method, an anonymous object works marvelously for simple values. (As an aside, best practice dictates that the user repository be retrieved from an IoC container, but for the purpose of this demonstration and for space considerations, I have hard-coded it here.) The logic in the action is very simple; we fetch a user based on credentials and return a value indicating if the user exists and if they have proper login access. Because the action here is a simple method in a controller class, it is also possible to write automated unit tests to make sure that the method behaves as expected under a variety of conditions.
The Route for this controller/action is likewise very simple.
The route does not define any parameters for username or password. This is because jQuery will append arguments to the route using the normal query string notation. I suspect, but have not verified, that if a route was specified with parameters such as /{username}/{password}, and a dynamic URL was constructed in JavaScript and no arguments were passed to it, the functionality would be identical.
The actual view contains the most involved code.
The form at the bottom contains two fields, Username and Password, and a simple input button that is used for submission. The click event of the login button calls jQuery's built in getJSON() method, which takes the following arguments:
- the URL that will be used to submit the AJAX request (the URL defined in the MVC routing table);
- an anonymous JavaScript object with properties identical to the method arguments of the action I am calling; and
- a callback method that takes the return result of the AJAX request as an argument. This result will have identical properties to the object we returned in our action method.
Based on the return value from Authorize(), I show a popup dialog indicating whether the user should be allowed to log in. (Best practices dictate that authorization and authentication be performed by two distinct services, but I have consolidated them here for brevity.) Because AJAX calls are asynchronous, it is important to remember that the click() event will likely exit before the getJSON() function has completed. If you add an hourglass or twirling Web 2.0 spiral (probably not the technical name), you will want to display it before getJSON() is called and hide it in the callback function instead of at the end of the click() event to ensure that it is displayed for the duration of the request.
That's all for now. I will post more on MVC later, but I think we can all agree that:
Print This PostThis was a triumph.
I'm making a note here: HUGE SUCCESS.
It's hard to overstate my satisfaction.--GlaDOS
God mode in Windows 7 not as cool as Rise of the Triad
I fondly remember the old days when games only came in 640x480 with cheap MIDI soundtracks and ugly enemy sprites. One such classic game (a personal favorite of mine) is Rise of the Triad, which featured a pretty kick-ass God mode in which the player could hurl orbs of energy from his or her hand and watch with glee as enemies dissipated into the aether.
Well, according to a recent cnet article, Redmond has added its own flavor of divine power to Windows 7. The hidden trick is to create a folder (anywhere on the file system) with the following name:
GodMode.{ED7BA470-8E54-465E-825C-99712043E01C}
The folder is magically transformed into a mega control panel with tons of power-user options for tweaking your favorite operating system. Although it lacks the certain malevolent satisfaction I get from Triad, the hack is still pretty neat. It does raise the question, though: why didn't Microsoft make this a standard shortcut for a vanilla Windows 7 install? I will leave you to draw your own theological parallels.
Print This PostCareers @ StackOverflow.com
StackOverflow.com has launched a new careers initiative that connects IT professionals with potential employers. Creating a profile is free, but search placement costs $99 annually. In the spirit of the holiday season, however, if you register before Jan. 1st the cost is only $29 for the first year. StackOverflow is associated with Joel Spolsky and Jeff Atwood, people I consider to be pioneers in the professional software developer community. You can read Jeff Atwood's official announcement on his blog.
If you're interested, my public profile is here: http://careers.stackoverflow.com/nicholascloud.
Print This PostForay into ASP.NET MVC
I've been working with ASP.NET MVC for the last week. It has seriously renewed my hope in a Microsoft web product. I am among the snobs who think ASP.NET WebForms is a terrible leaky abstraction. MVC changes all that by assuming that web standards and semantically meaningful markup are not only desirable, but necessary for a web application.
At first blush, it reminds me an awful lot of my previous experience with symfony, the popular PHP web framework. Splitting models, views, and controllers into distinct and decoupled files and classes is a very powerful concept, and buys the developer tremendous flexibility when changes on any of those tiers are mandated. A database change need not break the view; markup change need not affect page logic. It's a beautiful thing.
The routing system in MVC is also very powerful and effectively creates a paradigm shift for how we view URLs. MVC treats URL requests as logical paths to information as opposed to physical paths to pages. It does this by mapping specific URLs to controllers that have actions which contain the page logic to render given views. This is especially significant for SEO purposes where URLs are often crafted to communicate as much relevant content to search engines as possible. It also makes traditionally cryptic URLs far more reader friendly. (For example, the URL to this post contains the route /2009/10/foray-into-asp-net-mvc, which is more understandable than ?y=2009&m=10&title=foray%20into%20asp%20net%20mvc.) Routes are specified in the Global.ascx.cs file. The URL helpers that come with MVC allow internal links to be specified by Controller/Action, but renders them as specified in the global routing table. If a URL needs to change for a given resource, instead of finding all references to it in the source tree, only the routing table needs to be updated.
My favorite feature of MVC so far, though, is the simple fact that it doesn't muck with my markup. One thing I loathe about WebForms is that it insists on re-writing my HTML and making it damn near impossible to write standards-compliant code and adhere to web development best practices. In MVC, when I assign and id to an element, that's the id it gets -- not some hogwash like ctl00_ucPrimaryNav_primaryNavigationTable_ctrl1_lnkPrimaryNavigation. (WebForms is kind of like the government. When it says "I'm here to help", run away screaming.) This one tiny feature also frees up ASP.NET developers to leverage robust Javascript frameworks like jQuery and Prototype, feats that are not impossible in WebForms but require significant jury-rigging. The single-form-per-page has also been eliminated in favor of traditional HTML forms, which has always been a personal gripe of mine. (There are many scenarios where multiple forms on a page is a good idea.)
In place of the one genuinely useful feature of WebForms server controls, data binding, MVC introduces the concept of a strongly typed ViewModel that acts as the data source for a given view. This is a common development pattern gaining tremendous momentum in WPF circles (it is officially called Model-View-ViewModel in WPF and Silverlight), and it allows developers to interact with an object that contains all of a view's data, but is not itself the view. WebForms violates this pattern by confusing the view with it's own data, but MVC encourages it by supporting views that derive from System.Web.Mvc.ViewPage<T>, where T represents the ViewModel object to which the view will be bound. Fields in the view have IDs and names that correspond to properties in the ViewModel. They are automatically populated with the values of the ViewModel at runtime when the controller renders the view. This also provides a layer of encapsulation for the developer to leverage, masking the actual implementation of the data model, since model objects are not directly exposed to views. In fact, all that a view need know about is the interface that a ViewModel exposes, which is typically composed of simple types like strings, numbers, and boolean values. The view is agnostic to the data structures behind the ViewModel.
I am thrilled that Microsoft is supporting the MVC project as a viable alternative to WebForms. As I learn more about the framework, I will be sure to add more posts, including some code samples.
Print This Post


