Wednesday, February 10, 2010

Where's My Desktop!

The other day I got into work really early, hoping to have a productive morning. Unfortunately, my computer had other ideas. When it finished booting up I was greeted by an empty desktop and a host of applications complaining about needing a password. Geez, I don't even have coffee yet, how am I supposed to deal with this?! (not that I drink coffee...)

Anyway, being the lazy developer that I am, I promptly notified the IT staff and then fired up Google. I found a few posts mentioning the fact that my profile was mapped to a different location on disk (C:\windows\system32\config\systemprofile), but not much in the way of an explanation. They suggested copying files into that location, but that didn't seem like a good idea to me. Eventually I was contacted by one of my helpful coworkers who helped me resolve the issue by running the disk error checking utility (chkdsk.exe) and rebooting. Simple, huh?

So, what did I learn from all of this? Apparently, if Windows discovers that your profile is corrupted it will allow you to log in using a temporary profile so that you can fix the problem. Running chkdsk (with both options selected) may work, as it did for me, or it may also be possible to backup your files and have Windows regenerate some of the files that may be corrupt (but don't take my word for it).

I'll keep that info filed away for future reference, but I will probably never have this problem again *crosses fingers*...

Encryption and VARBINARY

Data loss is a scary thing. In one of the apps I have worked on it is particularly scary since some of the data is encrypted. In the beginning it was encrypted in such a way that it would be (hopefully) impossible to retrieve without the proper authorization. Essentially, the data would be junk if a finite number of users forgot their passwords. This was always lurking in the back of my mind. (You've never forgotten your password, have you?) Luckily we dropped that approach, but I didn't anticipate how we would actually lose data.

One day I discovered an interesting error was occurring. (Only in hindsight can I refer to it as "interesting".) It was a CryptographicException: Length of the data to decrypt is invalid. The application was attempting to load some encrypted data from the database and was repeatedly failing on a particular record. This is not good.

At first I thought: "Maybe there is a character or combination of characters in the source text that is causing the problem." Looking back I can see that it was a poor attempt at an explanation. To be fair, I was alerted to the problem by a user who also informed me that he had used a random text generation feature (possibly for the first time), so I was a little biased. I was able to verify that the data was an odd size (as expected) and the encryption algorithm expected blocks of a certain number of bytes. However, I could not reproduce the bug since I had no idea what the original source text was.

Fast-forward a week or two. The problem occurs again, but this time the user is working with a known value. I crack open the test system and, lo and behold, the error is reproducible! After doing some debugging and tracing I come to the conclusion that SQL Server is truncating my data. (How rude!?) From there it didn't take long for me to discover an interesting property of the column in question. Getting info on the table told me that the "TrimTrailingSpace" property was true (which corresponds to ANSI PADDING). It doesn't take a genius to figure out that something is wrong with that.

Luckily I found this article, which indicates that any alter of the column will turn off "TrimTrailingSpace", just what I wanted. So, what did I do? Something like this:

ALTER TABLE MyTable
ALTER COLUMN MyColumn VARBINARY(xxx);

Problem solved!

The New ASP.NET AJAX: Part 1 - Getting Started with the Script Loader

Background: I had an existing ASP.NET AJAX-enabled application and wanted to use the Script Manager control in conjunction with the new client-only Script Loader. I wasn’t quite sure how they would work together and there is (understandably) precious little in the way of documentation. Here is what I have found so far…
By the way, if you haven’t heard of the Script Loader then you can read about it here and here, or Google it (with Bing…)!


Include the Script Loader

My first thought was to just include the script loader’s script file (“start.js”) early, before the page scripts that would use it. Unfortunately, this line of code gave me grief.

if(typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();

It's automatically appended to script references so we’re stuck with it. This line of code predates the Script Loader, unfortunately. When it was written the AJAX JavaScript library lived in one big JavaScript file, so you either had it or you didn't. Today, the start script defines Sys (so that you can do things like Sys.require), but it doesn’t define the Application namespace. Therefore, the above line of code causes a “null or not an object” error. In order to get around this you just have to make sure that the start script is injected farther down the page than other script references that may include the offending line of code. In my case I used the ScriptManagerProxy control.

Define Your Scripts


This step is optional if you are just using the scripts from Microsoft or jQuery.

Sys.loader.defineScripts(
   {
      releaseUrl: "%/{0}.js",
      debugUrl: "%/{0}.debug.js"
   },
   [
      {
         name: "MyScript",
         executionDependencies: ["WebServices"],
         isLoaded: !!(MyControl)
      }
   ]
);

The first argument is named defaultScriptInfo, in case you’re wondering. Sounds interesting, doesn’t it? This is where you can put the common settings for all of the scripts that you are defining here. No need to repeat yourself. If you want you can pass null and be done with it.

The second argument is an array of JavaScript objects that tell the Script Loader everything it needs to know about each individual script(s). Here’s a breakdown of the properties:

name: This one is pretty obvious. I assume that you can use any arbitrary text here, but you may want to be selective since it will ultimately be used in JavaScript code. This is the name that you will use in other script definitions to indicate that it is a dependency (“WebServices” in the above example). It is also the attribute name that is tacked on to the Sys.scripts object.
releaseUrl: This is the url (sort of) that can be used to load our script in release mode. This is the literal url, with two exceptions. First, the special “%” character is a placeholder for “the place that I got this script from” (the script loader script). This means that if you downloaded the start script form CDN, then all of the other scripts that you request will also come from CDN. If you download it from your web server, then all of the other scripts will come from your web server. Also, “{0}” is replaced with the script name. This is useful if you’re defining a common url scheme.

debugUrl: Same as releaseUrl, except that this url is used in debug mode.

dependencies and executionDependencies: An array of script names. These are the scripts that must be present before your script can function. These two attributes accomplish this in slightly different ways. (Disclaimer: my current understanding of these options is based on reading through code as well as some guess work.) As I understand it, dependencies indicates that the script loader should wait for the dependencies before it attempts to load the script, whereas executionDependencies indicates that the script loader can fetch scripts in parallel and then execute them in the correct order (more on this later).

isLoaded: Tells the script loader whether or not your script is already loaded. This is useful for things like jQuery that may be commonly included as a static script reference, or for scripts that may or may not be included by the Script Manager.

Fix Your Script Files


If you have existing scripts that you want to load using the Script Loader, they probably look something like this:

<start of file>
bunch o' code...
<end of file>

In order to take full advantage of the script loader you will need to change your files to looks something like this:

<start of file>
;(function() {
   function execute () {
      bunch o' code...
   }

   if (window.Sys && Sys.loader) {
      Sys.loader.registerScript("MyScript", null, execute);
   }
   else {
      execute();
   }
}) ();
<end of file>

That bit at the end looks for the Script Loader and if it is found it tells the Script Loader that it is ready to execute whenever its dependency are loaded. Otherwise, it simply executes on the spot. That way it can function with or without the Script Loader.

With this in mind the distinction between dependencies and executionDependencies makes more sense. You may not be able to change a script to match this format. If that is the case, then the scripts cannot be fetched in parallel.

Using Your Scripts


Sys.require([Sys.scripts.MyScript], function() {
   bunch o' code...
});

It's as simple as that! The function that you provide as the second argument is executed whenever the required scripts have been loaded.