Friday, November 10, 2006

ASP.NET 2.0: Ambiguous match exception

Just ran into an ambiguous match exception which seemed to appear out of nowhere. A perfectly good ASP.NET 1.1 website starts throwing the 'Ambiguous Match Exception' when switched to ASP.NEt 2.0. I didn't recompile, or anything. To complicate things a bit, the Ambiguous match exception doesn't state why it is occuring. I guess Microsoft decided to pay tribute to the exception's name ;) Anyways, I figured it out using various blogs. ASP.NET 2.0 uses partial classes, where ASP.NET 1.x uses plain classes. 2.0 will automatically declare all named controls (controls that have an ID) as members of the final class. If a control ID overlaps with a (protected) member already declared in the class the exception occures. Note that this issue doesn't seem to occur using the ASP.NET development server. Check out these links for more info: Peter Johnson's Blog: Ambiguous match found. Advanced .NET Debugging: "Ambiguous match found" in a Web Control - a Possible Bug

Friday, November 3, 2006

ASP.NET 2.0 : Hierarchical datasources

While implementing a virtual file system for a customer I found myself in need of a custom hierarchical datasource. As usual, the MSDN website offered a good sample of such a class. Easy right? Anything but easy as it turns out. The sample code is all wrong. I ended up reading IL code to figure out how the SiteMapDataSource works. Reading IL is not exactly my idea of easy. Turns out the problem is in the way the HierarchicalDataSourceControl and HierarchicalDataSourceView interact. The DataSource control is supposed to be the workhorse of the two. The view is just a container for the results. In the sample however, the converse is true. That set me off in the wrong direction... The easiest thing to do is this:
  1. Create a node class that implement IHierarchyData
  2. Create a control derived from HierarchicalDataSourceControl.
  3. Create a specialized collection to hold your nodes and implement IHierarchicalEnumerable
  4. Implement a HierarchicalDataSourceView
  5. Override the GetHierarchicalView method in the HierarchicalDataSourceControl.

The first four steps are easy. Create the classes and implement the methods, pretty straight foreward. Using generics the collection just requires an implementation for IHierarchicalEnumerable.GetHierarchyData which can be as simple as a type cast since the node class implements IHierarchyData. I'll get back to implementing the nodes later. Implementing the HierarchicalDataSourceView is not that difficult either. It's just a wrapper around your collection. Store a copy of your collection class and return it in the Select method. That's all.

Overriding the GetHierarchicalView method
This is the method that does the actual work in the HierarchicalDataSource. The role of the viewPath parameter is the key to making this work; use it like a query. If you're loading objects from a database like me, the viewpath should be the unique key to the object. In the implementation use the viewPath to decide what to do:

  • If the viewPath is empty, use the root node of your hierarchy. If you want to include the root node in the hierarchy, return the root node itself. If you don't return it's children.
  • If viewPath is not empty, fetch the node pointed to by the viewPath and return it's children. This is crucial! Do not return the node itself, return it's children because when a view is requested for a node, it means the node was already returned in a previous call. If you return the node itself, the datasource will get stuck in an endless loop...

Implementing the nodes
The node implementation is nothing spectacular. Just make sure that the Path property returns something that you can process as a viewPath in your GetHierarchicalView implementation. If you want to bind a TreeView to your HierarchicalDataSourceControl you can use the Type property to hint the icon for the node. For example, when your hierarchy contains files and folders consider returning the mime type of the file so you can display the appropriate icon in the tree. I've compiled a simple ready-to-run sample (VS 2005) that uses a TreeView control to render the files in a given folder on disk.

Monday, October 9, 2006

ASP.NET 2.0 : Server hangups

While testing a new site I ran into a very annoying problem. The site kept locking up after something bad happened. I was unable to figure out exactly what was going on but this post gave me the golden tip. It describes how asserts (which I use for trapping potential errors during development) can cause the IIS worker process to hang(!) because they pop-up a dialog on the server. I've implemented the solution and it looks like the problem is solved. For future reference this is the fix:
      <assert logfilename="c:\log.txt" assertuienabled="false">
Serves me right though for running debug builds on a production server... :(

Friday, October 6, 2006

ResxEditor 1.0

It's not exactly easy to get customers to supply localized text in a usable format. Copy/pasting text from Word to Visual Studio is not exactly one of my favorite activities. So, I've decided to make life a bit easier for me and my customers.

Presenting the ResxEditor for .NET 2.0.
This tool allows you to edit resource files side by side. It recognizes the .NET convention of postfixing the locale to the file name. Though similar to PeopleWords ResxEditor , there is one major difference. This tool shows multiple resource files side by side. Allowing both me and my customers to manage resources and translate text in one easy tool.

ResxEditor is available for download now. You're free to do with it as you please though I would appreciate some credits if you decide to use it. Please feel free to contact me if you think the tool can be improved or you'd like to get the source code.

Tuesday, October 3, 2006

First Post

This is the first post of what I hope are many to come. This blog will be my online notebook. I'll post about the technical stuff that bothers me in everyday development as well as cool stuff that I'm looking forward to. I've got plenty of stuff to write about from the last project I've worked on. So hopefully I'll be able to help some other developers out there struggling with similar problems.