Wednesday, November 01, 2006

The dreaded "External component has thrown an exception" has a tendency to be quite unfriendly.  To assist in its unfriendliness, it doesn't report any of the goings-on that caused the error in the first place.

Examining the stack track may point you in the right direction but it usually doesn't really pin it down.

For instance, you may have an ASP.NET user control (.ascx) that you've created, but attempting to host it on a page and rendering it may result in the NSFE (Not-So-Friendly-Exception) without any indication as to what may have gone wrong.  Your exception stack may indicate something to the effect that the error occurred in the TemplateParser.GetParserCacheItemInternal method, preceded by BaseCompiler.ThrowIfCompilerErrors.  Still, not too enticing.

Such was the situation presented to me today by an application on which I was working.

Generally speaking the "External component has thrown an exception" error is usually indicative of an unresolvable error on your .aspx or .ascx page.  A missing function reference, for instance, where a control has a method name wired up to an event but the method has been since removed from the code behind.

In my case I had a custom server control that I had created embedded on my .ascx and I had double, triple, fourple checked that the correct .dll was on the server.

After some dabbling and experimenting, I discovered that it wasn't the presence of the server control that was bombing the site (because it would render), but rather the presence of some particular properties.  All of these properties have something in common - their data type: Color.

I thought maybe it was some odd color deserialization or type conversion but I ruled that one out pretty quickly.  This was working on 3-4 other test environments, why was it failing here?

As it turns out, the answer dawned on me after about 15 minutes of banging my head.  Due to the nature of this particular product, and how it's being hosted, I had removed all assemblies in the web.config's <compilation /> node and added back in the ones I had explicitly needed heretofore.  The assembly in which the Color type is defined (System.Drawing), however, was not among them.  Simply adding it back in fixed the problem.

<compilation defaultLanguage="c#" debug="false">
   <assemblies>
      <clear />
      <add ... />
      <add assembly="System.Drawing, Version=..." />
   </assemblies>
</compilation>

Word to the wise, if you're getting the NSFE "External component has thrown an exception" and you've double-checked that the page is indeed valid, verify your references!

Wednesday, November 01, 2006 9:47:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Wednesday, October 25, 2006

I had the distinct privilege of presenting on Refactoring at the Utah County .NET User Group tonight.  We had a great turnout and I'm fairly pleased with the presentation as a whole - I feel it went quite smoothly.  In past months the group had met at UVSC, but they're now in the process of moving to another location: NuSkin in Provo.  We met at their office off of EastBay.

The atmosphere was fantastic and there was great feedback and I believe that it worked out being beneficial for all in attendance (myself included).

I gleaned some talking points from an MSDN WebCast on Refactoring (as well as some demonstrations), but I believe it was all for the better.  Additionally, I used the Movie Rentals example from Martin Fowler's book to drive home the points made throughout the talk.

I've made the files (the PPT, the 'before refactoring' code, and 'after refactoring' code) available for download if you'd like to play with them.

Thanks to all that attended and for your feedback.  I look forward to the next time I have the opportunity!

Wednesday, October 25, 2006 2:53:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, October 24, 2006

Please join me tomorrow evening (Wednesday, October 25th, 2006) at 6:00 PM with the Utah County .NET User Group.  I have the privilege of speaking and sharing my thoughts on Refactoring.

In the event that you've been to the UCNUG meetings in the past, be forewarned that the meeting location has moved.  No longer at UVSC, the meetings will now be hosted by NuSkin (which makes the drive a little longer for me) at

NuSkin Network Operations Center (NOC)
1175 South 350 East
Provo, Utah 84606

Note, this is NOT the large building in downtown Provo but is rather in EastBay.  You can get to it by going to the south most Universty Avenue exit in Provo.

Hope to see you there!

Tuesday, October 24, 2006 3:03:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Monday, October 23, 2006

This might be useful to someone out there.  I had had this issue many months ago, but had to resolve it again today because I hadn't jotted down the solution - fortunately it only took about 2 minutes.

I am making use of the FolderBrowserDialog class in the .NET 2.0 Framework.  This class, as it's name implies, provides a graphical interface for browsing and selecting folders.

The issue was that when i made my call to .ShowDialog(), the dialog would appear but it was blank - only the 'Make New Folder', 'OK', and 'Cancel' buttons along with the description were visible, but the folder TreeView was not.  This would have worked from the get-go had a created my project as a Windows Forms project but I didn't; it's a Console application.

To solve the problem, I simply had to add the [STAThread()] to my Main() method - now it works like a charm.

[STAThread()]
public static void Main() {
   Application.EnableVisualStyles();
   Application.SetCompatibleTextRenderingDefault(false);
   Application.Run(new TestForm());
}

// ...then on the TestForm class

private void btnBrowseForFolder_Click(object sender, EventArgs e) {
   string folderPath = browseForFolder();
   // do something with the result
}

private string browseForFolder() {
   using ( FolderBrowserDialog dlg = new FolderBrowserDialog() ) {
      dlg.Description = "Select a folder";
      dlg.ShowNewFolderButton = true;
      dlg.RootFolder = Environment.SpecialFolder.MyComputer;
      return ( DialogResult.OK == dlg.ShowDialog(this) )
         ? dlg.SelectedPath
         : null;
   }
}

Monday, October 23, 2006 5:50:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [8]  |  Trackback
 Sunday, October 22, 2006

I was reminded at the Code Camp that I hadn't posted a little application that I wrote to facilitate the creation and testing of regular expressions.  There are many tools out there that are downloadable that provide this functionality, but I found it easier to talk about regular expressions from an instructional standpoint with my own tool and demonstrations.

I therefore set out to create such an application and it's freely downloadable here.  Essentially, the program allows you to create regular expressions and test them against some text/file of your choosing.  You can also save off a collection of regular expressions to file so that you can create your own library of expressions.  If you attended the User Group meeting you'll find that I've enhanced the UI slightly to make it more useful and instructional.

NOTE: The download is the source code and requires the .NET Framework 2.0 to work properly.

Enjoy!

Sunday, October 22, 2006 8:29:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback

For those interested, I've cleaned up and posted the code that I created that Utah Code Camp 2006 as a download right off of the blog.  Feel free to get it and enjoy!  I had a good time creating it.

So there you go!

Sunday, October 22, 2006 3:29:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback

At the code camp yesterday I was approached with a PInvoke question on how to handle a cross-unmanaged/managed function callback.  Back in my Win32 days (which is now some years on the past of doing native Win32 programming on a daily basis) this was common place, but I've not had this need in the .NET world - though the need does exist, as demonstrated by this gentleman's circumstances.

I took the task of figuring it out right there and quickly came up with this example that illustrates the technique that I took.

This example uses the frequently illustrated Win32 function EnumChildWindows to enumerate the child windows of a given window (e.g. controls on a form).  Sure, you can accomplish this by simply enumerating the .Controls collection on the form, but that's not what we're illustrating here - we want to do it via Win32 and a function callback.

The EnumChildWindows function accepts as a parameter a function pointer which will be called-back by the Win32 function once for each window found.  Once the callback returns FALSE (i.e. zero) the enumeration stops.

Setting up this function in managed code is trivial:

[SuppressUnmanagedCodeSecurity()]
private static class NativeMethods {
   internal delegate int EnumChildProc(IntPtr hWnd, IntPtr lParam);

   [DllImport("user32.dll")]
   internal static extern int EnumChildWindows(
         IntPtr hWnd,
         [MarshalAs(UnmanagedType.FunctionPtr)] EnumChildProc fn,
         IntPtr lParam);
}

Notice that in order to make the callback work I have to decorate the function callback parameter with the [MarshalAsAttribute] designating that as a FunctionPtr.

To test this functionality I created a simple form, added some controls (including a ListBox and Button).  I then named the button btnEnum and the ListBox lstOutput.  Then I wrote a little code in the Click event handler to call the unmanaged function, providing it with a callback function (via my delegate instance).  The callback function resolves the hWnd (window handle) of the window to the control and outputs the control name to the list box as follows:

private void btnEnum_Click(object sender, EventArgs e) {
   lstOutput.Items.Clear();
   NativeMethods.EnumChildWindows(this.Handle, enumChildren, IntPtr.Zero);
}

private int enumChildren(IntPtr hWnd, IntPtr lParam) {
   Control ctrl = Control.FromChildHandle(hWnd);
   lstOutput.Items.Add(ctrl.Name);
   return 1;   // indicate that we want to continue enumerating until we reach the end
}

That's about it...there's not much to it :)

Sunday, October 22, 2006 2:53:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Saturday, October 21, 2006

Today marked the day of the inaugural Utah Code Camp.  Brainchild of Pat Wright, the event was a great success.  From the beginning our goal was to have about 100 people in attendance, but despite having just around 90 registrants, only about 40-45 showed (I don't know the number accurately and am only guessing here).  Regardless, we all had a great time.

We had three tracks resulting in 15 presentations throughout the day from various volunteers and participants.  For instance, I had the opportunity to provide the keynote presentation (which in reality was little more than a 'welcome, this is how you get to the bathrooms when you need to go' presentation) and a talk on developing custom WinForms components.  We delved into the innards of using Designers, Editors, and Extenders and (I believe) everyone had a great time.

Other presentations included topics on SQL Server Worst Practices, some XNA stuff, a presentation on DirectX, Test Driven Development using NUnit, NHibernate 1.2.0, Client/Server application development, and more.

I haven't had a chance to see the results of the reviews but it sure seemed like everyone had a great time; it was very well received.  We're working on putting another one together in 6-8 months again and will undoubtedly be looking for speakers - we'd love to have more!

A fun way to spend a Saturday!

Saturday, October 21, 2006 4:50:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Friday, October 20, 2006

As a last minute reminder, the Utah Code Camp is tomorrow at Neumont University (10701 South River Front Parkway, South Jordan, Utah).  The event starts at 8:00 AM and runs to 5:00 PM.  This should be a fantastic event!  If you have not registered, please do and show up - you'll not want to miss it.

Friday, October 20, 2006 3:08:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, October 19, 2006

I have a web application that for one reason or another I'm currently unable to utilize AJAX to enable a nice, seamless, and seemingly postbackless experience.  I've maintained this particular application for several years now and it has a lot of AJAX-y like behaviors, but much of it feels like a hack and is somewhat unwieldy.  This particular application is (currently) specific to IE 6.0+.

I'm not going to wax too technical here since I want to keep this really light, but since IE 5.0 Microsoft has made a nice little COM object called Microsoft.XMLHTTP that allows a developer to submit http requests to a server and act on the results.  This is quite easily accomplished via Javascript on the client, as the following code demonstrates:

var http = new ActiveXObject("Microsoft.XMLHTTP");
http.onreadystatechange = function() {
   if ( 4 == http.readyState ) {
      // process the resulting response
      alert(http.responseText);
   }
};
http.open("POST", "http://someurl/here", true);
http.send("");

There's really nothing too it - and there's tons out there online that illustrate how to do this and I'll leave it to you to research it if you need to.  The above code, however, leaves something to be desired:  the way it's structured, I cannot reuse the XMLHTTP object - well, technically, I can, but my onreadystatechange event won't fire the second time.  I don't want to have to recreate an XMLHTTP instance for each and every request - I want to reuse the instance I already have.

This is easily solved by setting the onreadystatechange event after the call to the .open() method as such:

var http = new ActiveXObject("Microsoft.XMLHTTP");

function post(request) {
   http.open("POST", "http://someurl/here", true);
   http.onreadystatechange = function() {
      if ( 4 == http.readyState ) {
         // process the resulting response
         alert(http.responseText);
      }
   };
   http.send(request);
}

Now I've isolated the request portion into a method that I can call repeatedly and act on the results accordingly.

Simple.

Thursday, October 19, 2006 7:54:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback