Review: Google Gears

Ok, I think I grok it now. Google Gears is a huge cookie that can store files and SQL data. It also acts as a web server should the real internet be down. The API is all JavaScript.

The only caveat I see so far is getting people to install the Google Gears plug in. For MSIE, you get warning after warning about the plug in. You also seem to need to be an administrator to install the plug in. Without a sophisticated user base or a sympathetic IT department, the ActiveX component installation could be a show stopper.

As for integration with ASP.NET, ASP.NET has never been very friendly to JavaScript developers. ASP.NET changes the element ID’s, so you will need to code generate some JavaScript with <%= ClientId %> golden nuggets each time you reference a controls ID.

JavaScript counts as an out of bound call

Using Web Services from an ASP.NET 2.0 Application

Right click, add web service. Enter URL of web service. For example, http://localhost

VS2005 creates an App_WebReference folder with several XML files. Remember to right click and update reference next time you modify the webservice at localhost.

Web.config now has a new app setting with the URL. Personally, I’d like the application to use this URL instead of the ones found embedded in the XML files in App_WebReference.

To set the URLBehavior property, as far as I can tell, you need to be using a Web Application Project, not a Web Site Project. Conversion is not a light undertaking and the developer experience changes as you switch from one to the other.

Fortunately, it seems that the default ULRBehavior is dynamic for Web Site Projects.

ASP.NET DropDownList and Unexpected Data

The Problem
You are data binding to a table. One of the columns, say US state, should have a limited domain, but for various reasons, values outside of that range appear. For example, you might be importing the data from a second system that uses the state field for country and state.�
You don’t want to throw away the invalid state, for example the value, “UK” You want the user to correct them as they find them. The user should be shown the invalid value, given the option to leave it alone, but not given the option to change it to anything other than one of the fifty US states.
Plain HTML drop down controls can’t show a value that isn’t on the list of options.

<select>
<option value="OH">Ohio</option>
<option value="VA" selected="selected">Virginia</option>
</select>

You can’t set the value to “UK” because there isn’t an option.

Solutions.

Ugly solution #1. Use foreign keys. Make a foreign key between the state table and the address table. The data import package will blow up on invalid foreign keys. Make the data service group clean up the mess without the help of an ASP.NET application.

Ugly solution #2. Update the SqlDataSource to use a combination of valid and found values. So if the table was pubs, you would use

SELECT state value, state + ' Bad' description
FROM authors
where state not in (select state from states)
GROUP BY state
union
select state, state as v from states

This solution is ugly because what was an isolated component, a drop down that lists the states, now needs to know all the parameters necessary to run the same query that the datagrid is using.

Promising solution #3. Use a third party control that simulates a drop down through a series of divs. This would have worked, but the Telerik Rad ComboBox had the exact same behavior as the Microsoft DropDownList—it blows up on an unexpected value.
More Elegant Solution. For the ASP.NET DropDownList, we can create a new user control project, add the following class. This class overrides the DataBinding event. If the OnDataBinding event raises the dread out of range error, we torture the naming container until we get the value. We add it to the list with a description showing that we don’t approve of selecting it and select it. *Note, I didn’t invent this technique, I found variants on forums.

Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Text
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports Microsoft.VisualBasic
<DefaultProperty("Text"), ToolboxData("<{0}:BetterDropDown runat=server></{0}:BetterDropDown>")> _
Public Class BetterDropDown
Inherits System.Web.UI.WebControls.DropDownList
Protected Overrides Sub OnDataBinding(ByVal e As System.EventArgs)
Try
MyBase.OnDataBinding(e)
Catch OutOfRangeEx As System.ArgumentOutOfRangeException
Dim gvr As GridViewRow = CType(Me.NamingContainer, GridViewRow)
Dim drv As DataRowView = CType(gvr.DataItem, DataRowView)
Dim v As String = drv.Item(Me.DataValueField).ToString()
Me.ClearSelection()
Dim li As ListItem = New ListItem("BAD:" & v, v)
li.Selected = True
Me.Items.Insert(0, li)
Catch ex As Exception
Throw ex
End Try

End Sub

End Class

The client code looks like this. Notice that the DropDownList’s data source doesn’t need to reference the author’s table anymore, we don’t get an ugly error when an author is recorded as living in the state of UK

<%@ Register Assembly="BetterDD" Namespace="BetterDD" TagPrefix="asp" %>
<asp:GridView
ID="GridView1"
runat="server"
AutoGenerateColumns="False"
DataKeyNames="au_id"
DataSourceID="SqlDataSource2">
<Columns>
<asp:BoundField DataField="au_lname" HeaderText="au_lname" SortExpression="au_lname" />
<asp:BoundField DataField="au_fname" HeaderText="au_fname" SortExpression="au_fname" />
<asp:TemplateField HeaderText="state" SortExpression="state">
<ItemTemplate>
<asp:BetterDropDown
ID="DropDownList1"
runat="server"
SelectedValue='<%# Bind("State") %>'
DataTextField="State"
DataValueField="State"
DataSourceID="SqlDataSource1">
</asp:BetterDropDown>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>

<asp:SqlDataSource
ID=”SqlDataSource1″
runat=”server”
ConnectionString=”<%$ ConnectionStrings:pubsConnectionString %>”
SelectCommand=”select state, ‘y’ as v from states”></asp:SqlDataSource>
<asp:SqlDataSource
ID=”SqlDataSource2″
runat=”server”
ConnectionString=”<%$ ConnectionStrings:pubsConnectionString %>”
SelectCommand=”SELECT [au_id], [au_lname], [au_fname], [state] FROM [authors]“>
</asp:SqlDataSource>

Review: Mac on a Stick

Mac on a stick is a prove-it-can-be done project.  Meaning, it has no substative purpose other than proving that you can run a virtual Mac Classic from a thumb drive.

The vMac emulator requires assembling half a dozen files from multiple websites.  One assembled, you can launch the mac emulator, choose the boot disk and you are up.  Now the real work starts.

Unless you already are on a Mac, mounting the the disk on Windows requires using a slow, non-intuitive application to move files from Windows to the disk image.  It only works on disks that are not in use.  Ideally, one would like to drag and drop files between windows. 

Next, the vMac has no networking capabilities.  It might be nice to have a non-networked computer for doing things that require concentration and few distractions, such as writing a short story. However, so far I’ve only found some primitive text editors that are still available.  However, one I finish writing my great document, I want to be able to quickly transfer it to a real word processor where I can edit, print and publish it.  Getting files out of a Mac requires the same clunky utility.  Then you will face the challenge of getting any modern word processor to deal with the file you created.

In fact, any application that involves the creation or editing of  existing files is going to have this problem.  Mac on a stick not only brings back the good ole days of a simpler OS, but of the total lack of file format interop.

The Mac never really was a important gaming platform, so you can’t play a lot of compelling games on the vMac.  Utility applications I found on the remaining mac classic software download site have comparable windows versions, usually for free, better quality and also portable.

I’m thinking that Ubunutu on a stick is a more compelling idea. 

There may still be a single time when a emulator like vMac is interesting: When you don’t have administrator rights on a computer.  But the vMac sandbox is so limiting, you might as well be a standard user.

Boot Loader Personality Disorder

Boot loaders and the programmers who write them, are not the sort I’d want to invite to a party.  He would show up, untalkative and quietly change all the locks and board up all my roommates doors. They he’d paint my walls, re-arrange the furniture, change all the locks and then leave town.

I finally got the laptops to triple boot.  It was an ugly process.  Except for Linux, Vista and XP each wanted to act like they were the only operating system on the computer.  Vista and XP do not play well with each other, the XP boot loader can’t load Vista and Vista lets XP overwrite the MBR.

Linux tries to make sure everyone else can still boot by filling in the appropriate settings in the Grub configuration and menu files, but if you install a Windows operating system afterwards, XP and Vista will try to screw things up.

The configuration that finally works is to boot to GRUB first, Grub then can load either Ubuntu or the Vista Boot loader.  The Vista Boot loader, in turn lets you pick Vista or XP. 

I’ll post the utilites I used shortly. Ubuntu requires a live disk and cryptic grub commands to restore GRUB, Windows requires a free 3rd party utility that isn’t very well documented to get Vista and XP to play with each other.

I suspect that if the installation was XP -> Vista -> Linux, things would have been smoother.  However the machine already had Vista, then I added Linux, then XP. XP blew away Linux, and made it hard to boot to Vista anymore either.  So it took a lot of google fu to get thing working again.

Overview of Code Generation in the .NET World

Code generation is hand for common coding patterns, like the half dozen lines of code you for a class property. This will save you minutes of labor.

Code generation is really useful for meta-data drive programming. For example, if you have something that is a database, or looks like one, you may find yourself writing code to do the same half dozen operations with each table, such as fetch by primary key, insert, delete, update, undo an update, update within the context of a transaction, check for string lengths, and so on. Dynamic code that figures out how to do this at run time, for example, Fetch(table_name as object, pk_value as object) as object means you are working with late bound data types and it is potentially very expensive to look up the metadata on each call. It would be more efficient to code generate the tables and call Account.Fetch(pk_value as integer) as Account. And obviously either one of these patterns is more efficient than writing by hand the dozens of lines of code that it takes to fetch a row from a table and fill a business object.

Three big business object frameworks include CSLA, Subsonic, and .nettiers. CSLA and .nettiers are big frameworks with lots of fancy features. Subsonic is a relatively simple framework. It probably is better to pick any of the above than to try to write one’s own.

Metadata drive code generation is also a type of Object Relational Mapping (ORM). There is a “ORM impedance mismatch” between how the world looks from the standpoint of a relational model and an object oriented one. Sometimes the code generation frameworks do are able to translate from a database schema to objects without a change in semantics, sometimes not. For example, .nettiers can’t deal with tables with composite foreign keys.

To get code generation to work, you may have to adapt the templates or change the schema. If you have the luxury of completely rewriting your schema or if you don’t care what the database schema looks like, you might at this point decide to drop code generation and instead use nHibernate or the like, which takes the opposite approach—you write business objects and nHibernate decides how to save them to a database.

Code generation can be done in any language, although JSP/ASP like languages seem to be the preferred way to generate code. Template languages like to mix inline code in document templates. XSLT is an also ran that a bit hard to write. Microsoft itself uses CodeDom, which is like the HTML DOM, except the document is a .NET source file. It also has a reputation for being hard to write.

CodeSmith is almost just like ASP.NET and the code templates in Subsonic are ASP.NET pages. They are ordinary aspx files with source code instead of HTML around the golden nugget—(the inline code).

Code generation will become part of the build process, so a final component of a code generation is editing the nant or msbuild files to include the build. Both are a type of a script language with xml syntax. MsBuild is used by Visual Studio 2005, but nant has more features. MS-build’s feature list is more competitive once you include : http://msbuildtasks.tigris.org/